Exemplo n.º 1
0
    def _add_poly_to_matrix(self, p, adding_r=False):
        '''
        Saves the polynomial to the set of polynomials that will be used in create_matrix.
        Also updates the list of leading terms and monomials in the matrix with the new values.
        
        adding_r is only true when the r's are being added, this way it knows to keep adding new monomials to the heap
        for further r calculation
        '''
        startTime = time.time()
        if p is None:
            return
        self.matrix_polys.append(p)
        self.lead_term_set.add(Term(p.lead_term))

        for idx in zip(*np.where(p.coeff != 0)):
            idx_term = Term(tuple(idx))  #Get a term object
            if idx_term not in self.term_set:
                self.term_set.add(idx_term)
                #If r's being added, adds new monomial to the heap
                if adding_r:
                    if (idx_term not in self.lead_term_set):
                        self.monheap.heappush(idx_term)
        endTime = time.time()
        times["_add_poly_to_matrix"] += (endTime - startTime)
        return
Exemplo n.º 2
0
def initialize_np_matrix(new_polys, old_polys, items):
    '''
    Initialzes self.np_matrix to having just old_polys and new_polys in it
    matrix_terms is the header of the matrix, it lines up each column with a monomial
    '''
    # Added new things into the dictionary of constantly changing variables.
    items.update({
        'np_matrix': np.array([]),
        'original_lms': set(),
        'original_lm_dict': {},
        'lead_term_set': set(),
        'term_set': set(),
        'matrix_terms': [],
        'duplicate_lms': set(),
        'not_needed_lms': set()
    })

    for p in new_polys + old_polys:
        if p.lead_term != None:
            items['original_lms'].add(Term(p.lead_term))
            items['original_lm_dict'][Term(p.lead_term)] = p

    items = _add_poly_to_matrix(new_polys + old_polys, items)

    return items
Exemplo n.º 3
0
def _add_poly_to_matrix(p_list, items, adding_r=False):
    '''
    Takes in a single polynomial and adds it to the state matrix
    First adds a row of zeros, then goes through each monomial in the polynomial and puts it's coefficient in
    adding new columns as needed when new monomials are added.

    adding_r is only true when the r's are being added, this way it knows to keep adding new monomials to the heap
    for further r calculation

    returns the new lead_term_set
    '''
    for p in p_list:

        items['lead_term_set'].add(Term(p.lead_term))

        #Adds a new row of 0's if the matrix has any width
        if (items['np_matrix'].shape[0] != 0):
            zero_poly = np.zeros((1, items['np_matrix'].shape[1]))
            items['np_matrix'] = np.vstack((items['np_matrix'], zero_poly))

        for idx in zip(*np.where(p.coeff != 0)):
            idx_term = Term(tuple(idx))  #Get a term object
            # Grab each non-zero element, put it into matrix.
            idx_term.val = tuple(map(lambda i: int(i), idx_term.val))
            coeff_val = p.coeff[idx_term.val]

            # If already in term_set
            if idx_term in items['term_set']:
                # get index of label and np matrix to put into
                idx_where = np.argmax(
                    [i.val == idx_term.val for i in items['matrix_terms']])
                items['np_matrix'][-1, idx_where] = coeff_val

            # If new column needed
            else:
                # Make new column
                items['term_set'].add(idx_term)
                #If r's being added, adds new monomial to the heap
                if adding_r:
                    if (idx_term not in items['lead_term_set']):
                        items['monheap'].heappush(idx_term)
                        #print(idx_term.val)
                length_of_matrix = items['np_matrix'].shape[0]
                if length_of_matrix == 0:
                    items['np_matrix'] = np.zeros((1, 1))
                else:
                    zeros = np.zeros((length_of_matrix, 1))
                    items['np_matrix'] = np.hstack((items['np_matrix'], zeros))
                items['matrix_terms'].append(idx_term)
                items['np_matrix'][-1, -1] = coeff_val
    print("np_matrix:\n", items['np_matrix'])
    return items
Exemplo n.º 4
0
def calc_phi(a, b, items):
    '''Calculates the phi-polynomial's of the polynomials a and b.
    Returns:
        A tuple of the calculated phi's.
    '''
    lcm = _lcm(a, b)
    #updated to use monomial multiplication. Will crash for MultiCheb until that gets added
    a_diff = tuple([i - j for i, j in zip(lcm, a.lead_term)])
    b_diff = tuple([i - j for i, j in zip(lcm, b.lead_term)])

    #Keeping track of lead_terms
    if sum(a_diff) == 0 and sum(b_diff) == 0:
        items['duplicate_lms'].add(Term(a.lead_term))
    elif sum(a_diff) == 0:
        items['not_needed_lms'].add(Term(a.lead_term))
    elif sum(b_diff) == 0:
        items['not_needed_lms'].add(Term(b.lead_term))

    return a.mon_mult(a_diff), b.mon_mult(b_diff), items
Exemplo n.º 5
0
def test_push_pop():
    a0 = Term((0, 0, 1, 0, 0))
    a1 = Term((0, 1, 1, 3, 1))
    a2 = Term((0, 1, 1, 3, 0, 0, 0, 1))
    a3 = Term((2, 2, 2, 3, 4, 1, 4, 3))
    a4 = Term((0, 1, 1, 2, 2))
    maxh = MaxHeap()
    maxh.heappush(a1)
    maxh.heappush(a3)
    maxh.heappush(a0)
    maxh.heappush(a2)
    maxh.heappush(a4)
    assert maxh.heappop() == a3
    assert maxh.heappop() == a2

    maxh.heappush(a3)
    maxh.heappush(a3)

    assert maxh.heappop() == a3
    assert maxh.heappop() == a1
    assert maxh.heappop() == a4
    assert maxh.heappop() == a0
Exemplo n.º 6
0
    def update_lead_term(self, start=None):
        startTime = time.time()
        found = False

        non_zeros = set()
        for i in zip(*np.where(self.coeff != 0)):
            non_zeros.add(Term(i))
        if len(non_zeros) != 0:
            self.lead_term = max(non_zeros).val
            self.degree = sum(self.lead_term)
            self.lead_coeff = self.coeff[tuple(self.lead_term)]
        else:
            self.lead_term = None
            self.lead_coeff = 0

        endTime = time.time()
        times["leadTermCount"] += 1
        times["updateLeadTerm"] += (endTime - startTime)
        """ THE GENERATOR IS BROKEN RIGHT NOW. UNTIL FIXED USE THIS NEW, ALTHOUGH POSSIBLY SLOWER CODE.
Exemplo n.º 7
0
    def monomialList(self):
        '''
        return
        ------
        monomials : list of tuples
            list of monomials that make up the polynomial in degrevlex order
        '''
        start = time.time()
        monomialTerms = list()
        for i in zip(*np.where(self.coeff != 0)):
            monomialTerms.append(Term(i))
        monomialTerms.sort()

        monomials = list()
        for i in monomialTerms[::-1]:
            monomials.append(i.val)

        end = time.time()
        times["monomialsList"] += (end - start)
        self.sortedMonomials = monomials
        return monomials
Exemplo n.º 8
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
Exemplo n.º 9
0
def create_matrix(polys):
    '''
    Takes a list of polynomial objects (polys) and uses them to create a matrix. That is ordered by the monomial
    ordering. Returns the matrix and the matrix_terms, a list of the monomials corresponding to the rows of the matrix.
    '''
    #Gets an empty polynomial whose lm all other polynomial divide into.
    bigShape = np.maximum.reduce([p.coeff.shape for p in polys])

    #Gets a list of all the flattened polynomials.
    flat_polys = list()
    for poly in polys:
        #Gets a matrix that is padded so it is the same size as biggest, and flattens it. This is so
        #all flattened polynomials look the same.
        newMatrix = fill_size(bigShape, poly.coeff)
        flat_polys.append(newMatrix.ravel())

    #Make the matrix
    matrix = np.vstack(flat_polys[::-1])

    #Makes matrix_terms, a list of all the terms in the matrix.
    terms = np.zeros(bigShape, dtype = Term)
    for i,j in np.ndenumerate(terms):
        terms[i] = Term(i)
    matrix_terms = terms.ravel()

    #Sorts the matrix and matrix_terms by term order.
    matrix, matrix_terms = sort_matrix(matrix, matrix_terms)

    #Gets rid of any columns that are all 0.
    matrix, matrix_terms = clean_matrix(matrix, matrix_terms)
    #print(matrix)
    #print(matrix_terms)

    #Sorts the rows of the matrix so it is close to upper triangular.
    matrix = row_swap_matrix(matrix)

    return matrix, matrix_terms
Exemplo n.º 10
0
    def initialize_np_matrix(self, final_time=False):
        '''
        Initialzes self.np_matrix to having just old_polys and new_polys in it
        matrix_terms is the header of the matrix, it lines up each column with a monomial
        
        Now it sorts through the polynomials and if a polynomial is going to be reduced this time through
        it adds it and it's reducer to the matrix but doesn't use it for phi or r calculations.
        This makes the code WAY faster.
        '''
        startTime = time.time()

        self.matrix_terms = []
        self.np_matrix = np.array([])
        self.term_set = set()
        self.lead_term_set = set()
        self.original_lms = set()
        self.matrix_polys = list()

        if final_time:
            self._add_polys(self.new_polys + self.old_polys)
            for poly in self.new_polys + self.old_polys:
                self.original_lms.add(Term(poly.lead_term))
        else:
            old_polys = self.old_polys
            new_polys = self.new_polys
            polys = old_polys + new_polys

            polys = self.sorted_polys_monomial(polys)

            self.old_polys = list()
            self.new_polys = list()

            lms = defaultdict(list)
            for p in polys:
                lms[p.lead_term].append(p)
                pass

            polys_with_unique_lm = list()

            for i in lms:
                if len(lms[i]) > 1:  #It's duplicated
                    #self.duplicate_lms.add(Term(i))
                    self.new_polys.append(lms[i][0])
                    polys_with_unique_lm.append(lms[i][0])
                    lms[i].remove(lms[i][0])
                    self._add_polys(
                        lms[i]
                    )  #Still lets stuff be reduced if a poly reduces all of them.
                else:
                    polys_with_unique_lm.append(lms[i][0])

            divides_out = list()

            for i, j in itertools.permutations(polys_with_unique_lm, 2):
                if i in divides_out:
                    continue
                if self.divides(i, j):  # j divides into i
                    startStuff = time.time()
                    divides_out.append(i)
                    self._add_poly_to_matrix(i)
                    self._add_poly_to_matrix(
                        j.mon_mult(
                            tuple(a - b
                                  for a, b in zip(i.lead_term, j.lead_term))))

                pass

            for i in polys_with_unique_lm:
                if i not in divides_out:
                    self._add_poly_to_matrix(i)
                    if i in old_polys:
                        self.old_polys.append(i)
                    elif i in new_polys:
                        self.new_polys.append(i)
                    else:
                        raise ValueError("Where did this poly come from?")

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