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))
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
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])
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())
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()
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)
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)
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)
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)
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
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
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
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]))
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)
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
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)
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
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
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
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)
# 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 ----------
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
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
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
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
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)
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))