Example #1
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
Example #2
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
Example #3
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
Example #4
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
Example #5
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
    ----------