(a, b)
return None
Construct field isomorphism using PSLQ algorithm.
Construct field isomorphism using PSLQ algorithm.
Construct field isomorphism using PSLQ algorithm .
def field_isomorphism_pslq(a, b):
    """Construct field isomorphism using PSLQ algorithm. """
    if not a.root.is_real or not b.root.is_real:
        raise NotImplementedError("PSLQ doesn't support complex coefficients")

    f = a.minpoly
    g = b.minpoly.replace(f.gen)

    n, m, prev = 100, b.minpoly.degree(), None

    for i in range(1, 5):
        A = a.root.evalf(n)
        B = b.root.evalf(n)

        basis = [1, B] + [ B**i for i in xrange(2, m) ] + [A]

        dps, mp.dps = mp.dps, n
        coeffs = pslq(basis, maxcoeff=int(1e10), maxsteps=1000)
        mp.dps = dps

        if coeffs is None:
            break

        if coeffs != prev:
            prev = coeffs
        else:
            break

        coeffs = [S(c)/coeffs[-1] for c in coeffs[:-1]]

        while not coeffs[-1]:
            coeffs.pop()

        coeffs = list(reversed(coeffs))
        h = Poly(coeffs, f.gen, domain='QQ')

        if f.compose(h).rem(g).is_zero:
            d, approx = len(coeffs) - 1, 0

            for i, coeff in enumerate(coeffs):
                approx += coeff*B**(d - i)

            if A*approx < 0:
                return [ -c for c in coeffs ]
            else:
                return coeffs
        elif f.compose(-h).rem(g).is_zero:
            return [ -c for c in coeffs ]
        else:
            n *= 2

    return None
def field_isomorphism_pslq ( a , b ) : if not a . root . is_real or not b . root . is_real : raise NotImplementedError ( "PSLQ doesn't support complex coefficients" ) f = a . minpoly g = b . minpoly . replace ( f . gen ) n , m , prev = 100 , b . minpoly . degree ( ) , None for i in range ( 1 , 5 ) : A = a . root . evalf ( n ) B = b . root . evalf ( n ) basis = [ 1 , B ] + [ B ** i for i in xrange ( 2 , m ) ] + [ A ] dps , mp . dps = mp . dps , n coeffs = pslq ( basis , maxcoeff = int ( 1e10 ) , maxsteps = 1000 ) mp . dps = dps if coeffs is None : break if coeffs != prev : prev = coeffs else : break coeffs = [ S ( c ) / coeffs [ - 1 ] for c in coeffs [ : - 1 ] ] while not coeffs [ - 1 ] : coeffs . pop ( ) coeffs = list ( reversed ( coeffs ) ) h = Poly ( coeffs , f . gen , domain = 'QQ' ) if f . compose ( h ) . rem ( g ) . is_zero : d , approx = len ( coeffs ) - 1 , 0 for i , coeff in enumerate ( coeffs ) : approx += coeff * B ** ( d - i ) if A * approx < 0 : return [ - c for c in coeffs ] else : return coeffs elif f . compose ( - h ) . rem ( g ) . is_zero : return [ - c for c in coeffs ] else : n *= 2 return None