Exemple #1
0
def test_mon_mult_random():

    np.random.seed(988)

    #test with random matrices
    possible_dim = np.random.randint(1,5, (1,10))
    dim = possible_dim[0, np.random.randint(1,9)]

    shape = list()
    for i in range(dim):
        shape.append(np.random.randint(2,4))
    matrix1 = np.random.randint(1,11,(shape))
    M1 = MultiPower(matrix1)

    shape2 = list()
    for i in range(dim):
        shape2.append(np.random.randint(2,4))
    matrix2 = np.ones(shape2)
    M2 = MultiPower(matrix2)

    M3 = M1*M2

    for index, i in np.ndenumerate(M2.coeff):
        if sum(index) == 0:
            M4 = MultiPower.mon_mult(M1, index)
        else:
            M4 = M4 + MultiPower.mon_mult(M1, index)

    if M3.shape != M4.shape:
        new_M3_coeff, new_M4_coeff = utils.match_size(M3.coeff,M4.coeff)
    else:
        new_M3_coeff, new_M4_coeff = M3.coeff, M4.coeff

    assert np.allclose(new_M3_coeff, new_M4_coeff)
Exemple #2
0
def reduce_poly(poly, divisors, basisSet, permitted_round_error=1e-10):
    '''
    Divides a polynomial by a set of divisor polynomials using the standard
    multivariate division algorithm and returns the remainder
    parameters
    ----------
    poly : polynomial object
        the polynomial to be divided by the Groebner basis
    divisors : list of polynomial objects
        polynomials to divide poly by
    basisSet : set of tuples
        The monomials that make up a basis for the vector space
    returns
    -------
    polynomial object
        the remainder of poly / divisors
    '''
    remainder_shape = np.maximum.reduce([p.shape for p in divisors])
    remainder = np.zeros(remainder_shape)

    for term in zip(*np.where(poly.coeff != 0)):
        if term in basisSet:
            remainder[term] += poly.coeff[term]
            poly.coeff[term] = 0
    poly.__init__(poly.coeff, clean_zeros=False)

    # while poly is not the zero polynomial
    while np.any(poly.coeff):
        divisible = False
        # Go through polynomials in set of divisors
        for divisor in divisors:
            # If the LT of the divisor divides the LT of poly
            if divides(divisor.lead_term, poly.lead_term):
                # Get the quotient LT(poly)/LT(divisor)
                LT_quotient = np.subtract(poly.lead_term, divisor.lead_term)

                poly_to_subtract_coeff = divisor.mon_mult(LT_quotient,
                                                          returnType='Matrix')
                # Match sizes of poly_to_subtract and poly so
                # poly_to_subtract.coeff can be subtracted from poly.coeff
                poly_coeff, poly_to_subtract_coeff = match_size(
                    poly.coeff, poly_to_subtract_coeff)
                new_coeff = poly_coeff - \
                    (poly.lead_coeff/poly_to_subtract_coeff[tuple(divisor.lead_term+LT_quotient)])*poly_to_subtract_coeff

                new_coeff[np.where(
                    np.abs(new_coeff) < permitted_round_error)] = 0

                for term in zip(*np.where(new_coeff != 0)):
                    if term in basisSet:
                        remainder[term] += new_coeff[term]
                        new_coeff[term] = 0

                poly.__init__(new_coeff, clean_zeros=False)
                divisible = True
                break
    return remainder
Exemple #3
0
    def __sub__(self, other):
        '''
        Subtraction of two MultiCheb polynomials.

        Parameters
        ----------
        other : MultiCheb

        Returns
        -------
        MultiCheb
            The coeff values are the result of self.coeff - other.coeff.
        '''
        if self.shape != other.shape:
            new_self, new_other = match_size(self.coeff, other.coeff)
        else:
            new_self, new_other = self.coeff, other.coeff
        return MultiCheb((new_self - (new_other)), clean_zeros=False)
Exemple #4
0
    def __add__(self, other):
        '''
        Addition of two MultiPower polynomials.

        Parameters
        ----------
        other : MultiPower

        Returns
        -------
        MultiPower object
            The sum of the coeff of self and coeff of other.

        '''
        if self.shape != other.shape:
            new_self, new_other = match_size(self.coeff, other.coeff)
        else:
            new_self, new_other = self.coeff, other.coeff
        return MultiPower((new_self + new_other), clean_zeros=False)
Exemple #5
0
    def __mul__(self, other):
        '''
        Multiplication of two MultiPower polynomials.

        Parameters
        ----------
        other : MultiPower object

        Returns
        -------
        MultiPower object
            The result of self*other.

        '''
        if self.shape != other.shape:
            new_self, new_other = match_size(self.coeff, other.coeff)
        else:
            new_self, new_other = self.coeff, other.coeff

        return MultiPower(convolve(new_self, new_other))
Exemple #6
0
    def __add__(self, other):
        '''
        Addition of two MultiCheb polynomials.

        Parameters
        ----------
        other : MultiCheb

        Returns
        -------
        MultiCheb
            The sum of the coeff of self and coeff of other.

        '''
        if self.shape != other.shape:
            new_self, new_other = match_size(self.coeff, other.coeff)
        else:
            new_self, new_other = self.coeff, other.coeff

        return MultiCheb(new_self + new_other)
Exemple #7
0
def bivariate_roots(f, g):
    """Calculates the common roots of f and g using the bezout resultant method.

    Parameters
    ----------
    f, g : MultiCheb objects

    Returns
    -------
    roots

    """
    F, G = utils.match_size(f.coeff, g.coeff)
    n = max(F.shape)
    # F, G = np.zeros((n,n)), np.zeros((n,n))
    # F = F + utils.match_size(F, f_coeffs)[1] # Square matrix for f
    # G = G + utils.match_size(G, g_coeffs)[1] # Square matrix for g

    A = np.zeros((n - 1, n - 1, 2 * n - 1))
    a, b, c = (np.vstack([np.ones(
        (n - 1, 1)), 2]) / 2).T, np.zeros(n), np.ones(n) / 2
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            AA = np.array([[0] + list(F[:, i - 1][::-1])])
            v = G[:, j - 1][::-1].reshape((-1, 1))
            X, ignored = DLP(AA, v, a, b, c)
            if i == 1 or j == 1:
                cc = np.zeros(max(i, j))
                cc[0] = 1
            else:
                cc = np.zeros(i + j - 1)
                cc[-1] = .5
                cc[abs(i - j)] = .5
                cc = cc[::-1]
            for k in range(len(cc)):
                A[:, :, -1 - k] = A[:, :, -1 - k] + X[1:, 1:] * cc[-1 - k]

    nrmA = np.linalg.norm(A[:, :, -1], 'fro')
    for ii in range(A.shape[2]):
        if np.linalg.norm(A[:, :, ii], 'fro') / nrmA > 1e-20:
            break
    A = A[:, :, ii:]

    ns = A.shape
    AA = A.reshape(ns[0], ns[1] * ns[2], order='F')

    n = ns[0]
    v = np.random.rand(n, 1)
    a, b, c = (np.vstack([np.ones(
        (n - 1, 1)), 2]) / 2).T, np.zeros(n), np.ones(n) / 2
    X, Y = DLP(AA, v, a, b, c)
    yvals, V = sLA.eig(Y, -X)

    y = yvals
    x = np.divide(V[-2, :], V[-1, :])

    t = np.copy(x)
    x = x[np.logical_and(np.logical_and(np.imag(y) == 0,
                                        abs(y) < 1),
                         abs(x) < 1)]
    y = y[np.logical_and(np.logical_and(np.imag(y) == 0,
                                        abs(y) < 1),
                         abs(t) < 1)]

    return list(zip(x, y))