Ejemplo n.º 1
0
def PolyDivModOverZn(a: poly, b: poly, n: int) -> (poly, poly):
    if n < 1:
        raise ValueError
    if n==1:
        raise ZeroDivisionError
    a = poly(np.mod(a.coef, n))
    b = poly(np.mod(b.coef, n))
    a = a.trim()
    b = b.trim()
    deg_a, deg_b = len(a.coef), len(b.coef)
    if deg_a < deg_b:
        return poly([0]), a
    else:
        f = poly(b.coef[::-1]).trim()
        g = PolyInverseModOverZn(f, deg_a - deg_b + 1, n)
        if g is None:
            raise ZeroDivisionError
        q = (poly(a.coef[::-1]).trim() * g).truncate(deg_a - deg_b + 1)  # q:=rev_n(a)g mod x^(n-m+1)
        q = poly(np.mod(q.coef, n))
        q = poly(q.coef[::-1]).trim()  # q:=rev_(n-m)(q)
        if len(q.coef) < deg_a - deg_b + 1:
            q.coef = np.concatenate([np.zeros(deg_a - deg_b + 1 - len(q)), q.coef])
        bq = poly(np.mod((b * q).coef, n))
        r = a - bq
        r = poly(np.mod(r.coef, n))
        q = poly(np.mod(q.coef, n))
        r = r.trim()
        q = q.trim()
        return q, r
Ejemplo n.º 2
0
def PolyDivModOverQ(a: poly, b: poly) -> (poly, poly):
    if not b.coef.any(): #если полином нулевой
        raise ZeroDivisionError
    a = a.trim()
    b = b.trim()
    n, m = len(a.coef), len(b.coef)  # степени полиномов
    if n < m:
        return poly([0]), a
    else:
        f = poly(b.coef[::-1]).trim() #f:=rev_m(b)
        g = PolyInverseModOverQ(f, n - m + 1) #q inverse of f modulo x^(n-m+1)
        q = (poly(a.coef[::-1]).trim() * g).truncate(n - m + 1)#q:=rev_n(a)g mod x^(n-m+1)
        q = poly(q.coef[::-1]).trim() #q:=rev_(n-m)(q)
        if len(q.coef) < n - m + 1:
            q.coef = np.concatenate([np.zeros(n - len(q)), q.coef])
        r = a - b * q #r:=a-bq
        r = r.trim()
        q = q.trim()
        return q, r
Ejemplo n.º 3
0
def PolyDivModOverQ(a: Poly, b: Poly) -> (Poly, Poly):
    if not b.coef.any():
        raise ZeroDivisionError

    a = a.trim()
    b = b.trim()
    n, m = len(a.coef), len(b.coef)

    if n < m:
        return Poly([0]), a
    else:
        f = rev(b, m)
        g = PolyInverseModOverQ(f, n - m + 1)
        q = (rev(a, n) * g).truncate(n - m + 1)
        q = rev(q, n - m + 1)

        if len(q.coef) < n - m + 1:
            q.coef = np.concatenate([np.zeros(n - len(q)), q.coef])

        r = a - b * q
        r = r.trim()
        q = r.trim()
        return q, r
Ejemplo n.º 4
0
def PolyDivModOverZn(a: Poly, b: Poly, mod_r: int) -> (Poly, Poly):
    if mod_r < 1:
        raise ValueError

    if mod_r == 1:
        raise ZeroDivisionError

    a = Poly(np.mod(a.coef, mod_r))
    b = Poly(np.mod(b.coef, mod_r))

    a = a.trim()
    b = b.trim()
    n, m = len(a.coef), len(b.coef)

    if n < m:
        return Poly([0]), a
    else:
        f = rev(b, m)
        g = PolyInverseModOverZn(f, n - m + 1, mod_r)

        if g is None:
            raise ZeroDivisionError

        q = (rev(a, n) * g).truncate(n - m + 1)
        q = Poly(np.mod(q.coef, mod_r))
        q = rev(q, n - m)

        if len(q.coef) < n - m + 1:
            q.coef = np.concatenate([np.zeros(n - m + 1 - len(q)), q.coef])

        bq = Poly(np.mod((b * q).coef, mod_r))
        r = a - bq
        r = Poly(np.mod(r.coef, mod_r))
        q = Poly(np.mod(q.coef, mod_r))
        r = r.trim()
        q = q.trim()
        return q, r
Ejemplo n.º 5
0
def PolyDivModOverZn(a, b: Poly, n: int):  #−> (Poly , Poly ):
    a = a.trim()
    b = b.trim()
    if (n < 1):
        raise ValueError
    if (a.degree() < b.degree()):
        return Poly([0]), a
    m = a.degree() - b.degree()
    revb = Poly(b.coef[::-1])
    rrevb = PolyInverseModOverZn(revb, m + 1, n)
    if (rrevb is None):
        raise ZeroDivisionError("")
    reva = Poly(a.coef[::-1])
    q1 = reva * rrevb
    q1 = q1.truncate(m + 1)
    q = Poly(q1.coef[::-1])
    q = modPoly(q, n)
    bq = b * q
    bq = modPoly(bq, n)
    r = modPoly(a - b * q, n)
    r = Poly(r.coef[::-1])
    r.trim()
    r = Poly(r.coef[::-1])
    return q, r
Ejemplo n.º 6
0
def PolyInverseModOverQ(f: Poly, r: int):  #r=2, предполагаем f0[0] = 1
    f = f.trim()
    if (r < 1):
        raise ValueError
    #f = modPoly(f, zn)
    f0 = f.coef[0]
    if (f0 != Fraction(1, 1)):
        f0 = 1 / f0
    if (f0 == Fraction(0, 1)):
        return None
    g = Poly(f0)

    l = int(math.ceil(math.log2(r)))

    for k in range(1, l + 1):
        g = (2 * g - f * (g**2))
        g = g.truncate(2**k)
    return g
Ejemplo n.º 7
0
def rev(p: Poly, n: int) -> Poly:
    p = p.trim()
    result = p.coef[::-1]
    if len(p.coef) < n:
        result = np.concatenate([np.zeros(n - len(p.coef)), result])
    return Poly(result)