Ejemplo n.º 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
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
0
            # 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
    ----------
    poly : polynomial object