예제 #1
0
def test_evaluate_at():
    cheb = MultiCheb(np.array([[0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]]))
    value = cheb.evaluate_at((2, 5))
    assert (value == 828)

    value = cheb.evaluate_at((.25, .5))
    assert (np.isclose(value, -.5625))
예제 #2
0
def _match_poly_dim(poly1, poly2):
    # Do nothing if they are already the same dimension
    if poly1.dim == poly2.dim:
        return poly1, poly2

    poly_type = ''
    if type(poly1) == MultiPower and type(poly2) == MultiPower:
        poly_type = 'MultiPower'
    elif type(poly1) == MultiCheb and type(poly2) == MultiCheb:
        poly_type = 'MultiCheb'
    else:
        raise ValueError('Polynomials must be the same type')

    poly1_vars = poly1.dim
    poly2_vars = poly2.dim
    max_vars = max(poly1_vars, poly2_vars)

    if poly1_vars < max_vars:
        for j in range(max_vars - poly1_vars):
            coeff_reshaped = poly1.coeff[..., np.newaxis]
        if poly_type == 'MultiPower':
            poly1 = MultiPower(coeff_reshaped)
        elif poly_type == 'MultiCheb':
            poly1 = MultiCheb(coeff_reshaped)
    elif poly2_vars < max_vars:
        for j in range(max_vars - poly2_vars):
            coeff_reshaped = poly2.coeff[..., np.newaxis]
        if poly_type == 'MultiPower':
            poly2 = MultiPower(coeff_reshaped)
        elif poly_type == 'MultiCheb':
            poly2 = MultiCheb(coeff_reshaped)

    return poly1, poly2
예제 #3
0
def testCoordinateVector():
    poly = MultiCheb(np.array([[0,1,0],[0,0,1],[1,0,0]]))
    VB = [(2,0),(1,2),(0,1),(1,0)]
    GB = [MultiCheb(np.array([[0,0,0],[0,0,0],[0,0,1]]))] # LT is big so nothing gets reduced

    cv = rf.coordinateVector(poly, GB, VB)
    assert(cv == [1,1,1,0])
예제 #4
0
 def test_add(self):
     a1 = np.arange(27).reshape((3, 3, 3))
     Test2 = MultiCheb(a1)
     a2 = np.ones((3, 3, 3))
     Test3 = MultiCheb(a2)
     addTest = Test2 + Test3
     self.assertTrue(addTest.coeff.all() == (Test2.coeff +
                                             Test3.coeff).all())
예제 #5
0
def test_add():
    """Test Multivariate Chebyshev polynomial addition."""
    t = np.arange(27).reshape((3, 3, 3))
    poly1 = MultiCheb(t)
    poly2 = MultiCheb(np.ones((3, 3, 3)))
    S = poly1 + poly2  # the sum of the polynomials
    result = (S.coeff == (poly1.coeff + poly2.coeff))
    assert result.all()
예제 #6
0
def test_mult():
    """Test Multivariate Chebyshev polynomial multiplication."""
    test1 = np.array([[0, 1], [2, 1]])
    test2 = np.array([[2, 2], [3, 0]])
    cheb1 = MultiCheb(test1)
    cheb2 = MultiCheb(test2)
    new_cheb = cheb1 * cheb2
    truth = MultiCheb(np.array([[4, 3.5, 1], [5, 9, 1], [3, 1.5, 0]]))
    assert np.allclose(new_cheb.coeff, truth.coeff)
예제 #7
0
 def test_mult(self):
     test1 = np.array([[0, 1], [2, 1]])
     test2 = np.array([[2, 2], [3, 0]])
     cheb1 = MultiCheb(test1)
     cheb2 = MultiCheb(test2)
     new_cheb = cheb1 * cheb2
     truth = np.array([[4, 3.5, 1], [5, 9, 1], [3, 1.5, 0]])
     test = new_cheb.coeff.all() == truth.all()
     self.assertTrue(test)
예제 #8
0
def test_mult_diff():
    '''
    Test Multivariate Chebyshev polynomial multiplication.
    Test implementation with different shape sizes
    '''
    c1 = MultiCheb(np.arange(0, 4).reshape(2, 2))
    c2 = MultiCheb(np.ones((2, 1)))
    p = c1 * c2
    truth = MultiCheb(np.array([[1, 2.5, 0], [2, 4, 0], [1, 1.5, 0]]))
    assert np.allclose(p.coeff, truth.coeff)
예제 #9
0
 def test_mult_diff(self):
     '''
     #TODO: Verify by hand...
     Test implementation with different shape sizes
     '''
     c1 = MultiCheb(np.arange(0, 4).reshape(2, 2))
     c2 = MultiCheb(np.ones((2, 1)))
     p = c1 * c2
     truth = np.array([[1, 2.5, 0], [2, 4, 0], [1, 1.5, 0]])
     test = p.coeff.all() == truth.all()
     self.assertTrue(test)
예제 #10
0
def sm_to_poly(items, rows, reduced_matrix, power):
    '''
    Takes a list of indicies corresponding to the rows of the reduced matrix and
    returns a list of polynomial objects
    '''
    shape = []
    p_list = []
    matrix_term_vals = [i.val for i in items['matrix_terms']]

    # Finds the maximum size needed for each of the poly coeff tensors
    for i in range(len(matrix_term_vals[0])):
        # add 1 to each to compensate for constant term
        shape.append(max(matrix_term_vals, key=itemgetter(i))[i] + 1)
    # Grabs each polynomial, makes coeff matrix and constructs object
    for i in rows:
        p = reduced_matrix[i]
        p[np.where(abs(p) < global_accuracy)] = 0
        coeff = np.zeros(shape)
        for j, term in enumerate(matrix_term_vals):
            coeff[term] = p[j]

        if power:
            poly = MultiPower(coeff)
            p_list.append(poly)
        else:
            poly = MultiCheb(coeff)
            p_list.append(poly)
    return p_list
예제 #11
0
def get_poly_from_matrix(rows,matrix,matrix_terms,power):
    '''
    Takes a list of indicies corresponding to the rows of the reduced matrix and
    returns a list of polynomial objects
    '''
    shape = []
    p_list = []
    matrix_term_vals = [i.val for i in matrix_terms]

    # Finds the maximum size needed for each of the poly coeff tensors
    for i in range(len(matrix_term_vals[0])):
        # add 1 to each to compensate for constant term
        shape.append(max(matrix_term_vals, key=itemgetter(i))[i]+1)
    # Grabs each polynomial, makes coeff matrix and constructs object
    for i in rows:
        p = matrix[i]
        coeff = np.zeros(shape)
        for j,term in enumerate(matrix_term_vals):
            coeff[term] = p[j]

        if power:
            poly = MultiPower(coeff)
        else:
            poly = MultiCheb(coeff)

        if poly.lead_term != None:
            p_list.append(poly)
    return p_list
예제 #12
0
    def solve(self, qr_reduction=True, reducedGroebner=True):
        '''
        The main function. Initializes the matrix, adds the phi's and r's, and then reduces it. Repeats until the reduction
        no longer adds any more polynomials to the matrix. Print statements let us see the progress of the code.
        '''
        MultiCheb.clearTime()
        MultiPower.clearTime()
        startTime = time.time()

        polys_were_added = True
        i = 1  #Tracks what loop we are on.
        while polys_were_added:
            #print("Starting Loop #"+str(i))
            #print("Num Polys - ", len(self.new_polys + self.old_polys))
            self.initialize_np_matrix()
            self.add_phi_to_matrix()
            self.add_r_to_matrix()
            self.create_matrix()
            #print(self.np_matrix.shape)
            polys_were_added = self.reduce_matrix(
                qr_reduction=qr_reduction, triangular_solve=False
            )  #Get rid of triangular solve when done testing
            i += 1

        #print("Basis found!")

        self.get_groebner()
        if reducedGroebner:
            self.reduce_groebner_basis()

        endTime = time.time()
        #print("WE WIN")
        print("Run time was {} seconds".format(endTime - startTime))
        print(times)
        MultiCheb.printTime()
        MultiPower.printTime()
        #print("Basis - ")
        #for poly in self.groebner_basis:
        #    print(poly.coeff)
        #break #print just one

        return self.groebner_basis
예제 #13
0
def calc_r(m,new_polys,old_polys,items):
        '''
        Finds the r polynomial that has a leading monomial m
        Returns the polynomial.
        '''
        for p in new_polys + old_polys:
                l = list(p.lead_term)
                if all([i<=j for i,j in zip(l,m)]) and len(l) == len(m): #Checks to see if l divides m
                    c = [j-i for i,j in zip(l,m)]
                    if not l == m: #Make sure c isn't all 0
                        return p.mon_mult(c)
        if items['power']:
            return MultiPower(np.array([0]))
        else:
            return MultiCheb(np.array([0]))
예제 #14
0
def poly2cheb(P):
    """
    Convert a standard polynomial to a chebyshev polynomial in multiple dimensions.
    
    Args:
        P (): The multi-dimensional standard polynomial. (tensor?)

    Returns:
        (MultiCheb): The multi-dimensional chebyshev polynomial.

    """
    dim = len(P.shape)
    A = P.coeff
    for i in range(dim):
        A = np.apply_along_axis(conv_poly, i, A)
    return MultiCheb(A)
예제 #15
0
def _random_poly(_type, dim):
    '''
    Generates a random polynomial that has the form
    c_1x_1 + c_2x_2 + ... + c_nx_n where n = dim and each c_i is a randomly
    chosen integer between 0 and 1000.
    '''
    _vars = _get_var_list(dim)

    random_poly_shape = [2 for i in range(dim)]

    random_poly_coeff = np.zeros(tuple(random_poly_shape), dtype=int)
    for var in _vars:
        random_poly_coeff[var] = np.random.randint(1000)

    if _type == 'MultiCheb':
        return MultiCheb(random_poly_coeff), _vars
    else:
        return MultiPower(random_poly_coeff), _vars
예제 #16
0
def test_cheb2poly():
    c1 = MultiCheb(np.array([[0, 0, 0], [0, 0, 0], [0, 1, 1]]))
    c2 = cheb2poly(c1)
    truth = np.array([[1, -1, -2], [0, 0, 0], [-2, 2, 4]])
    assert np.allclose(truth, c2.coeff)

    #test2
    c3 = MultiCheb(np.array([[3, 1, 4, 7], [8, 3, 1, 2], [0, 5, 6, 2]]))
    c4 = cheb2poly(c3)
    truth2 = np.array([[5, -19, -4, 20], [7, -3, 2, 8], [-12, -2, 24, 16]])
    assert np.allclose(truth2, c4.coeff)

    c4_1 = poly2cheb(c4)
    assert np.allclose(c3.coeff, c4_1.coeff)

    #Test3
    c5 = MultiCheb(
        np.array([[3, 1, 3, 4, 6], [2, 0, 0, 2, 0], [3, 1, 5, 1, 8]]))
    c6 = cheb2poly(c5)
    truth3 = np.array([[0, -9, 12, 12, -16], [2, -6, 0, 8, 0],
                       [12, -4, -108, 8, 128]])
    assert np.allclose(truth3, c6.coeff)

    #test4 - Random 1D
    matrix2 = np.random.randint(1, 100, random.randint(1, 30))
    c7 = MultiCheb(matrix2)
    c8 = cheb2poly(c7)
    c9 = poly2cheb(c8)
    assert np.allclose(c7.coeff, c9.coeff)

    #Test5 - Random 2D
    shape = list()
    for i in range(2):
        shape.append(random.randint(2, 30))
    matrix1 = np.random.randint(1, 50, (shape))
    c10 = MultiCheb(matrix1)
    c11 = cheb2poly(c10)
    c12 = poly2cheb(c11)
    assert np.allclose(c10.coeff, c12.coeff)

    #Test6 - Random 4D
    shape = list()
    for i in range(4):
        shape.append(random.randint(2, 15))
    matrix1 = np.random.randint(1, 50, (shape))
    c13 = MultiCheb(matrix1)
    c14 = cheb2poly(c13)
    c15 = poly2cheb(c14)
    assert np.allclose(c13.coeff, c15.coeff)
예제 #17
0
    def create_matrix(self):
        startTime = time.time()

        biggest_shape = np.maximum.reduce(
            [p.coeff.shape for p in self.matrix_polys])

        if self.power:
            biggest = MultiPower(np.zeros(biggest_shape), clean_zeros=False)
        else:
            biggest = MultiCheb(np.zeros(biggest_shape), clean_zeros=False)
        self.np_matrix = biggest.coeff.flatten()
        self.np_matrix = np.array(self.np_matrix, dtype=np.longdouble)

        flat_polys = list()
        for poly in self.matrix_polys:
            startFill = time.time()
            newMatrix = self.fill_size(biggest.coeff, poly.coeff)
            flat_polys.append(newMatrix.ravel())
            endFill = time.time()
            times["fill"] += (endFill - startFill)

        self.np_matrix = np.vstack(flat_polys[::-1])

        terms = np.zeros(biggest_shape, dtype=Term)
        startTerms = time.time()
        for i, j in np.ndenumerate(terms):
            terms[i] = Term(i)
        endTerms = time.time()
        times["terms"] += (endTerms - startTerms)

        self.matrix_terms = terms.flatten()
        self.sort_matrix()
        self.clean_matrix()

        self.np_matrix = self.row_swap_matrix(self.np_matrix)

        endTime = time.time()
        times["create_matrix"] += (endTime - startTime)
        pass
예제 #18
0
    def get_polys_from_matrix(self, rows, reduced_matrix):
        '''
        Takes a list of indicies corresponding to the rows of the reduced matrix and
        returns a list of polynomial objects
        '''
        startTime = time.time()
        shape = []
        p_list = []
        matrix_term_vals = [i.val for i in self.matrix_terms]

        # Finds the maximum size needed for each of the poly coeff tensors
        for i in range(len(matrix_term_vals[0])):
            # add 1 to each to compensate for constant term
            shape.append(max(matrix_term_vals, key=itemgetter(i))[i] + 1)
        # Grabs each polynomial, makes coeff matrix and constructs object
        for i in rows:
            p = reduced_matrix[i]
            if clean:
                if np.sum(np.abs(p)) < global_accuracy:
                    continue
            #p[np.where(abs(p) < global_accuracy/1.e5)] = 0
            coeff = np.zeros(shape)
            for j, term in enumerate(matrix_term_vals):
                coeff[term] = p[j]

            if self.power:
                poly = MultiPower(coeff)
            else:
                poly = MultiCheb(coeff)

            if poly.lead_term != None:
                #poly.coeff = poly.coeff/poly.lead_coeff  #This code is maybe sketchy, maybe good.
                #print(poly.coeff)
                p_list.append(poly)
        endTime = time.time()
        times["get_poly_from_matrix"] += (endTime - startTime)
        return p_list
예제 #19
0
def reduce_poly(poly, divisors, 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
    ----------
    polynomial : polynomial object
        the polynomial to be divided by the Groebner basis
    divisors : list of polynomial objects
        polynomials to divide poly by

    return
    ------
    polynomial object
        the remainder of poly / divisors
    '''
    startTime = time.time()

    # init remainder polynomial
    if type(poly) == MultiCheb:
        remainder = MultiCheb(np.zeros((1, 1)))
    else:
        remainder = MultiPower(np.zeros((1, 1)))

    # 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:
            poly, divisor = _match_poly_dim(poly, divisor)
            # 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 = tuple(
                    np.subtract(poly.lead_term, divisor.lead_term))

                poly_to_subtract = divisor.mon_mult(LT_quotient)

                # Match sizes of poly_to_subtract and poly so
                # poly_to_subtract.coeff can be subtracted from poly.coeff
                poly, poly_to_subtract = poly.match_size(
                    poly, poly_to_subtract)

                new_coeff = poly.coeff - \
                    (poly.lead_coeff/divisor.lead_coeff)*poly_to_subtract.coeff
                new_coeff[np.where(abs(new_coeff) < permitted_round_error)] = 0
                poly.__init__(new_coeff)

                divisible = True
                break

        if not divisible:
            remainder, poly = remainder.match_size(remainder, poly)

            polyLT = poly.lead_term

            # Add lead term to remainder
            remainder_coeff = remainder.coeff
            remainder_coeff[polyLT] = poly.coeff[polyLT]
            remainder.__init__(remainder_coeff)

            # Subtract LT from poly
            new_coeff = poly.coeff
            new_coeff[polyLT] = 0
            poly.__init__(new_coeff)

    endTime = time.time()
    times["reducePoly"] += (endTime - startTime)

    return remainder
예제 #20
0
def test_mon_mult():
    """
    Tests monomial multiplication using normal polynomial multiplication.
    """

    #Simple 2D test cases
    cheb1 = MultiCheb(np.array([[0, 0, 0], [0, 0, 0], [0, 0, 1]]))
    mon1 = (1, 1)
    result1 = cheb1.mon_mult(mon1)
    truth1 = np.array([[0, 0, 0, 0], [0, 0.25, 0, 0.25], [0, 0, 0, 0],
                       [0, 0.25, 0, 0.25]])

    assert np.allclose(result1.coeff, truth1)

    #test with random matrices
    cheb2 = np.random.randint(-9, 9, (4, 4))
    C1 = MultiCheb(cheb2)
    C2 = cheb2poly(C1)
    C3 = MultiCheb.mon_mult(C1, (1, 1))
    C4 = MultiPower.mon_mult(C2, (1, 1))
    C5 = poly2cheb(C4)

    assert np.allclose(C3.coeff, C5.coeff)

    # test results of chebyshev mult compared to power multiplication
    cheb3 = np.random.randn(5, 4)
    c1 = MultiCheb(cheb3)
    c2 = MultiCheb(np.ones((4, 2)))
    for index, i in np.ndenumerate(c2.coeff):
        if sum(index) == 0:
            c3 = c1.mon_mult(index)
        else:
            c3 = c3 + c1.mon_mult(index)
    p1 = cheb2poly(c1)
    p2 = cheb2poly(c2)
    p3 = p1 * p2
    p4 = cheb2poly(c3)
    assert np.allclose(p3.coeff, p4.coeff)

    # test results of chebyshev mult compared to power multiplication in 3D
    cheb4 = np.random.randn(3, 3, 3)
    a1 = MultiCheb(cheb4)
    a2 = MultiCheb(np.ones((3, 3, 3)))
    for index, i in np.ndenumerate(a2.coeff):
        if sum(index) == 0:
            a3 = a1.mon_mult(index)
        else:
            a3 = a3 + a1.mon_mult(index)
    q1 = cheb2poly(a1)
    q2 = cheb2poly(a2)
    q3 = q1 * q2
    q4 = cheb2poly(a3)
    assert np.allclose(q3.coeff, q4.coeff)
예제 #21
0
            # Go through the indexes of variables not in the basis in
            # decreasing order. It must be done in decreasing order for the
            # roots to be calculated correctly, since the vars with lower
            # indexes depend on the ones with higher indexes
            for pos in list(vars_not_in_basis.keys())[::-1]:
                GB_poly = _get_poly_with_LT(vars_not_in_basis[pos], GB)
                var_value = GB_poly.evaluate_at(root) * -1
                root[pos] = var_value
        roots.append(root)
    endEndStuff = time.time()
    times["endStuff"] = (endEndStuff - startEndStuff)
    endTime = time.time()
    totalTime = (endTime - startTime)
    print("Total run time for roots is {}".format(totalTime))
    print(times)
    MultiCheb.printTime()
    MultiPower.printTime()
    Polynomial.printTime()
    print((times["basis"]+times["multMatrix"])/totalTime)
    return roots

def multMatrix(poly, GB, basis):
    '''
    Finds the matrix of the linear operator m_f on A = C[x_1,...,x_n]/I
    where f is the polynomial argument. The linear operator m_f is defined
    as m_f([g]) = [f]*[g] where [f] represents the coset of f in
    A. Since m_f is a linear operator on A, it can be represented by its
    matrix with respect to the vector space basis.

    parameters
    ----------
예제 #22
0
def Macaulay(initial_poly_list, global_accuracy = 1.e-10):
    """
    Macaulay will take a list of polynomials and use them to construct a Macaulay matrix.

    parameters
    --------
    initial_poly_list: A list of polynomials
    global_accuracy: How small we want a number to be before assuming it is zero.
    --------

    Returns
    -----------
    Reduced Macaulay matrix that can be passed into the root finder.
    -----------
    """
    times = {}
    startTime = time.time()
    MultiCheb.clearTime()
    MultiPower.clearTime()

    Power = bool
    if all([type(p) == MultiPower for p in initial_poly_list]):
        Power = True
    elif all([type(p) == MultiCheb for p in initial_poly_list]):
        Power = False
    else:
        print([type(p) == MultiPower for p in initial_poly_list])
        raise ValueError('Bad polynomials in list')

    poly_list = []
    degree = find_degree(initial_poly_list)
    
    startAdding = time.time()
    for i in initial_poly_list:
        poly_list = add_polys(degree, i, poly_list)
    endAdding = time.time()
    times["adding polys"] = (endAdding - startAdding)
        
    startCreate = time.time()
    matrix, matrix_terms = create_matrix(poly_list)
    endCreate = time.time()
    times["create matrix"] = (endCreate - startCreate)
    
    #plt.matshow([i==0 for i in matrix])
            
    startReduce = time.time()
    matrix = rrqr_reduce(matrix)
    matrix = clean_zeros_from_matrix(matrix)
    non_zero_rows = np.sum(abs(matrix),axis=1) != 0
    matrix = matrix[non_zero_rows,:] #Only keeps the non_zero_polymonials
    endReduce = time.time()
    times["reduce matrix"] = (endReduce - startReduce)
    
    #plt.matshow([i==0 for i in matrix])
    
    startTri = time.time()
    matrix = triangular_solve(matrix)
    matrix = clean_zeros_from_matrix(matrix)
    endTri = time.time()
    times["triangular solve"] = (endTri - startTri)
    
    #plt.matshow([i==0 for i in matrix])
    
    startGetPolys = time.time()
    rows = get_good_rows(matrix, matrix_terms)
    final_polys = get_poly_from_matrix(rows,matrix,matrix_terms,Power)
    endGetPolys = time.time()
    times["get polys"] = (endGetPolys - startGetPolys)
    
    endTime = time.time()
    print("Macaulay run time is {} seconds".format(endTime-startTime))
    print(times)
    MultiCheb.printTime()
    MultiPower.printTime()
    #for poly in final_polys:
    #    print(poly.lead_term)
    return final_polys
예제 #23
0
def roots(polys, method='Groebner'):
    '''
    Finds the roots of the given list of polynomials

    parameters
    ----------
    polys : list of polynomial objects
        polynomials to find the common roots of

    returns
    -------
    list of numpy arrays
        the common roots of the polynomials
    '''

    times["reducePoly"] = 0
    Polynomial.clearTime()

    startTime = time.time()

    # Determine polynomial type
    poly_type = ''
    if (all(type(p) == MultiCheb for p in polys)):
        poly_type = 'MultiCheb'
    elif (all(type(p) == MultiPower for p in polys)):
        poly_type = 'MultiPower'
    else:
        raise ValueError('All polynomials must be the same type')
    # Calculate groebner basis
    startBasis = time.time()
    if method == 'Groebner':
        G = Groebner(polys)
        GB = G.solve()
    else:
        GB = Macaulay(polys)
    endBasis = time.time()
    times["basis"] = (endBasis - startBasis)
    dim = max(g.dim for g in GB)  # dimension of the polynomials

    # Check for no solutions
    if len(GB) == 1 and all([i == 1 for i in GB[0].coeff.shape]):
        print("No solutions")
        return -1

    startRandPoly = time.time()
    # Make sure ideal is zero-dimensional and get random polynomial
    f, var_list = _random_poly(poly_type, dim)
    if not _test_zero_dimensional(var_list, GB):
        print("Ideal is not zero-dimensional; cannot calculate roots.")
        return -1
    endRandPoly = time.time()
    times["randPoly"] = (endRandPoly - startRandPoly)

    # Get multiplication matrix
    startVectorBasis = time.time()
    VB, var_dict = vectorSpaceBasis(GB)
    endVectorBasis = time.time()
    times["vectorBasis"] = (endVectorBasis - startVectorBasis)
    #print("VB:", VB)
    #print("var_dict:", var_dict)
    startMultMatrix = time.time()
    m_f = multMatrix(f, GB, VB)
    endMultMatrix = time.time()
    times["multMatrix"] = (endMultMatrix - startMultMatrix)

    startEndStuff = time.time()
    # Get list of indexes of single variables and store vars that were not
    # in the vector space basis.
    var_indexes = np.array([-1 for i in range(dim)])
    vars_not_in_basis = {}
    for i in range(len(var_list)):
        var = var_list[i]  # x_i
        if var in var_dict:
            var_indexes[i] = var_dict[var]
        else:
            # maps the position in the root to its variable
            vars_not_in_basis[i] = var

    vnib = False
    if len(vars_not_in_basis) != 0:
        vnib = True

    # Get left eigenvectors
    eig = np.linalg.eig(m_f.T)[1]
    num_vectors = eig.shape[1]
    eig_vectors = [eig[:, i].tolist()
                   for i in range(num_vectors)]  # columns of eig

    roots = []
    for v in eig_vectors:
        root = np.zeros(dim, dtype=complex)
        # This will always work because var_indexes and root have the
        # same length - dim - and var_indexes has the variables in the
        # order they should be in the root
        for i in range(dim):
            x_i_pos = var_indexes[i]
            if x_i_pos != -1:
                root[i] = v[x_i_pos] / v[0]
        if vnib:
            # Go through the indexes of variables not in the basis in
            # decreasing order. It must be done in decreasing order for the
            # roots to be calculated correctly, since the vars with lower
            # indexes depend on the ones with higher indexes
            for pos in list(vars_not_in_basis.keys())[::-1]:
                GB_poly = _get_poly_with_LT(vars_not_in_basis[pos], GB)
                var_value = GB_poly.evaluate_at(root) * -1
                root[pos] = var_value
        roots.append(root)
    endEndStuff = time.time()
    times["endStuff"] = (endEndStuff - startEndStuff)
    endTime = time.time()
    totalTime = (endTime - startTime)
    print("Total run time for roots is {}".format(totalTime))
    print(times)
    MultiCheb.printTime()
    MultiPower.printTime()
    Polynomial.printTime()
    print((times["basis"] + times["multMatrix"]) / totalTime)
    return roots
예제 #24
0
    def reduce_matrix(self, qr_reduction=True, triangular_solve=False):
        '''
        Reduces the matrix fully using either QR or LU decomposition. Adds the new_poly's to old_poly's, and adds to
        new_poly's any polynomials created by the reduction that have new leading monomials.
        Returns-True if new polynomials were found, False otherwise.
        '''
        startTime = time.time()
        if qr_reduction:
            independentRows, dependentRows, Q = self.fullRank(self.np_matrix)
            fullRankMatrix = self.np_matrix[independentRows]

            startRRQR = time.time()
            reduced_matrix = self.rrqr_reduce(fullRankMatrix)

            non_zero_rows = np.sum(abs(reduced_matrix), axis=1) != 0

            reduced_matrix = reduced_matrix[
                non_zero_rows, :]  #Only keeps the non_zero_polymonials
            endRRQR = time.time()
            times["rrqr_reduce"] += (endRRQR - startRRQR)
            '''
            #If I decide to use the fully reduce method.
            Q,R = qr(self.np_matrix)
            reduced_matrix = self.fully_reduce(R)
            non_zero_rows = np.sum(abs(reduced_matrix),axis=1)>0 ##Increasing this will get rid of small things.
            reduced_matrix = reduced_matrix[non_zero_rows,:] #Only keeps the non_zero_polymonials
            '''

            startTri = time.time()
            if triangular_solve:
                reduced_matrix = self.triangular_solve(reduced_matrix)
                if clean:
                    reduced_matrix = self.clean_zeros_from_matrix(
                        reduced_matrix)
            endTri = time.time()
            times["triangular_solve"] += (endTri - startTri)

            #plt.matshow(reduced_matrix)
            #plt.matshow([i==0 for i in reduced_matrix])
            #plt.matshow([abs(i)<self.global_accuracy for i in reduced_matrix])
        else:
            #This thing is very behind the times.
            P, L, U = lu(self.np_matrix)
            reduced_matrix = U
            #reduced_matrix = self.fully_reduce(reduced_matrix, qr_reduction = False)

        #Get the new polynomials
        new_poly_spots = list()
        old_poly_spots = list()
        startLooking = time.time()
        already_looked_at = set(
        )  #rows whose leading monomial we've already checked
        for i, j in zip(*np.where(reduced_matrix != 0)):
            if i in already_looked_at:  #We've already looked at this row
                continue
            elif self.matrix_terms[
                    j] in self.lead_term_set:  #The leading monomial is not new.
                if self.matrix_terms[
                        j] in self.original_lms:  #Reduced old poly. Only used if triangular solve is done.
                    old_poly_spots.append(i)
                already_looked_at.add(i)
                continue
            else:
                already_looked_at.add(i)
                new_poly_spots.append(
                    i)  #This row gives a new leading monomial
        endLooking = time.time()
        times["looking"] += (endLooking - startLooking)

        if triangular_solve:
            self.old_polys = self.get_polys_from_matrix(
                old_poly_spots, reduced_matrix)
        else:
            self.old_polys = self.new_polys + self.old_polys
        self.new_polys = self.get_polys_from_matrix(new_poly_spots,
                                                    reduced_matrix)

        endTime = time.time()
        times["reduce_matrix"] += (endTime - startTime)

        if len(self.old_polys + self.new_polys) == 0:
            print(
                "ERROR ERROR ERROR ERROR ERROR NOT GOOD NO POLYNOMIALS IN THE BASIS FIX THIS ASAP!!!!!!!!!!!!!"
            )
            print(reduced_matrix)
            print(times)
            MultiCheb.printTime()

        return len(self.new_polys) > 0
예제 #25
0
def test_init_():
    C = MultiPower(np.array([[-1, 0, 1], [0, 0, 0]]))
    D = MultiCheb(np.array([[-1, 0, 0], [0, 1, 0], [1, 0, 0]]))
    with pytest.raises(ValueError):
        grob = Groebner([C, D])
    pass
예제 #26
0
파일: dev.py 프로젝트: dmurphy4/Groebner
sys.path.append('/'.join(
    os.path.dirname(os.path.abspath(__file__)).split('/')[:-1]))
from groebner.multi_cheb import MultiCheb
from groebner.polys.multi_power import MultiPower
from groebner.grobner.grobner import Grobner
from groebner.grobner import maxheap

#a1 = np.arange(3**3).reshape(3,3,3)
#a2 = np.arange(3**3).reshape(3,3,3)
#a1[0,0,0] = 7
#a2[1,1,1] = 9

a1 = np.arange(2**2).reshape(2, 2)
a2 = np.array([[2, 2], [2, 2]])
a3 = np.array([[1, 0], [2, 0]])
c1 = MultiCheb(a1)
c2 = MultiCheb(a2)
c3 = MultiCheb(a3)
c_list = [c1, c2, c3]
grob = Grobner(c_list)
grob.add_s_to_matrix()
#print(grob.label)
#print('mat')
#print(grob.matrix)
grob.add_r_to_matrix()
#print(grob.matrix)
#
#a3 = np.array([[0,0],[0,1]])
#a4 = np.array([[0,1],[0,0]])
#c3 = MultiCheb(a3)
#c4 = MultiCheb(a4)
예제 #27
0
def test_evaluate_at2():
    cheb = MultiCheb(np.array([[0, 0, 0, 1], [0, 0, 0, 0], [0, 0, .5, 0]]))
    value = cheb.evaluate_at((2, 5))
    assert (np.isclose(value, 656.5))