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 calc_s(self, a, b): ''' Calculates the S-polynomial of a,b ''' lcm = self._lcm(a, b) a_coeffs = np.zeros_like(a.coeff) a_coeffs[tuple([i - j for i, j in zip(lcm, a.lead_term) ])] = 1. / (a.coeff[tuple(a.lead_term)]) b_coeffs = np.zeros_like(b.coeff) b_coeffs[tuple([i - j for i, j in zip(lcm, b.lead_term) ])] = 1. / (b.coeff[tuple(b.lead_term)]) if isinstance(a, MultiPower) and isinstance(b, MultiPower): b_ = MultiPower(b_coeffs) a_ = MultiPower(a_coeffs) elif isinstance(a, MultiCheb) and isinstance(b, MultiCheb): b_ = MultiCheb(b_coeffs) a_ = MultiCheb(a_coeffs) else: raise ValueError('Incompatiable polynomials') a1 = a_ * a b1 = b_ * b s = a_ * a - b_ * b #self.polys.append(s) return s
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 test_mult(): 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.all(), truth.coeff.all())
def test_add(): a1 = np.arange(27).reshape((3, 3, 3)) Test2 = MultiCheb(a1) a2 = np.ones((3, 3, 3)) Test3 = MultiCheb(a2) addTest = Test2 + Test3 assert addTest.coeff.all() == (Test2.coeff + Test3.coeff).all()
def test_mult_diff(): ''' 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.all(), truth.coeff.all())
def test_mon_mult(): mon = (1, 2) Poly = MultiCheb( np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])) mon_matr = MultiCheb( np.array([[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]])) P1 = mon_matr * Poly P2 = MultiCheb.mon_mult(Poly, mon) assert np.allclose(P1.coeff.all(), P2.coeff.all())
def sm_to_poly(self, rows, reduced_matrix): ''' 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 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] 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 self.power: poly = MultiPower(coeff) p_list.append(poly) else: poly = MultiCheb(coeff) p_list.append(poly) return p_list
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 The polynomial f for which to find the matrix m_f. GB: list of polynomial objects Polynomials that make up a Groebner basis for the ideal basis : list of tuples The monomials that make up a basis for the vector space A return ------ multOperatorMatrix : square numpy array The matrix m_f ''' # Reshape poly's coefficienet matrix if it is not in the same number # of variables as the polynomials in the Groebner basis. # (i.e. len(shape) is the number of variables the polynomial is in) numVars = len(GB[0].shape) polyVars = len(poly.coeff.shape) if polyVars != numVars: new_shape = [i for i in poly.coeff.shape] for j in range(numVars-polyVars): new_shape.append(1) if type(poly) is MultiPower: poly = MultiPower(poly.coeff.reshape(tuple(new_shape))) if type(poly) is MultiCheb: poly = MultiCheb(poly.coeff.reshape(tuple(new_shape))) dim = len(basis) operatorMatrix = np.zeros((dim, dim)) for i in range(dim): monomial = basis[i] poly_ = poly.mon_mult(monomial) operatorMatrix[:,i] = coordinateVector(poly_, GB, basis) return operatorMatrix
def calc_r(self, m): ''' Finds the r polynomial that has a leading monomial m Returns the polynomial. ''' for p in self.new_polys + self.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 self.power: return MultiPower(np.array([0])) else: return MultiCheb(np.array([0]))
def add_r_to_matrix(self): ''' Makes Heap out of all monomials, and finds lcms to add them into the matrix ''' for monomial in self.term_set: m = list(monomial) for p in self.polys: l = list(p.lead_term) if all([i <= j for i, j in zip(l, m)]) and len(l) == len(m): c = [j - i for i, j in zip(l, m)] c_coeff = np.zeros(np.array(self.largest_mon.val) + 1) c_coeff[tuple(c)] = 1 if isinstance(p, MultiCheb): c = MultiCheb(c_coeff) elif isinstance(p, MultiPower): c = MultiPower(c_coeff) r = c * p self.add_poly_to_matrix(r) break pass
def test_mon_mult(): """ Tests monomial multiplication using normal polynomial multiplication. """ mon = (1, 2) Poly = MultiCheb( np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])) mon_matr = MultiCheb( np.array([[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]])) P1 = mon_matr * Poly P2 = MultiCheb.mon_mult(Poly, mon) mon2 = (0, 1, 1) Poly2 = MultiCheb(np.arange(1, 9).reshape(2, 2, 2)) mon_matr2 = MultiCheb(np.array([[[0, 0], [0, 1]], [[0, 0], [0, 0]]])) T1 = mon_matr2 * Poly2 T2 = MultiCheb.mon_mult(Poly2, mon2) assert np.allclose(P1.coeff.all(), P2.coeff.all()) assert np.allclose(T1.coeff.all(), T2.coeff.all())
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])
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)
import numpy as np import pandas as pd from scipy.linalg import lu import random import time #Local imports from multi_cheb import MultiCheb from multi_power import MultiPower import maxheap from groebner_class import Groebner from convert_poly import cheb2poly, poly2cheb import groebner_basis from root_finder import roots matrix1 = np.random.randint(-10,10,(2,3)) matrix2 = np.random.randint(-30,30,(3,3)) T1 = MultiCheb(matrix1) T2 = MultiCheb(matrix2) P1 = cheb2poly(T1) P2 = cheb2poly(T2) roots([P1,P2]) roots([T1,T2])
def reduce_poly(poly, divisors): ''' Divides a polynomial by the Groebner basis 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 divid poly by return ------ polynomial object the unique remainder of poly divided by self.GB ''' remainder_coeff = np.zeros_like(poly.coeff, dtype=float) # 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: # 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)) new = divisor.mon_mult(LT_quotient) # Get max value of shapes to know how much to pad max_shape = np.maximum(poly.coeff.shape, new.coeff.shape) poly_pad = np.subtract(max_shape, poly.coeff.shape) poly.__init__(pad_matrix(poly_pad, poly.coeff), clean_zeros=False) new_pad = np.subtract(max_shape, new.coeff.shape) new.__init__(pad_matrix(new_pad, new.coeff), clean_zeros=False) new_coeff = poly.coeff - \ (poly.lead_coeff/divisor.lead_coeff)*new.coeff new_coeff[np.where(abs(new_coeff) < 1.e-10)]=0 poly.__init__(new_coeff, clean_zeros=False) print("poly:\n", poly.coeff) divisible = True break if not divisible: lcm = np.maximum(poly.coeff.shape, remainder_coeff.shape) remainder_pad = np.subtract(lcm, remainder_coeff.shape) remainder_coeff = \ pad_matrix(remainder_pad, remainder_coeff) # Add lead term to remainder polyLT = poly.lead_term remainder_coeff[polyLT] = poly.coeff[polyLT] # Subtract LT from poly new_coeff = poly.coeff new_coeff[poly.lead_term] = 0 poly.__init__(new_coeff) if (type(poly) == MultiPower): return MultiPower(remainder_coeff) else: return MultiCheb(remainder_coeff)
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))
import sys, os import numpy as np from multi_cheb import MultiCheb from multi_power import MultiPower from groebner import Grobner from groebner 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)