def test__approx_QQ( self ): M = ''' [ ( 0, 0, 1/2, 0, 0, -1/2, 1/2 ), ( 0, -1, 0, 0, 0, 0, 1/2 ), ( 1/2, 0, 0, 1/2, 0, 0, 1 ), ( 0, 0, 1/2, -1, 0, -1/2, 0 ), ( 0, 0, 0, 0, -1, 0, -1/2 ), (-1/2, 0, 0, -1/2, 0, -1, -1/2 ), ( 1/2, 1/2, 1, 0, -1/2, -1/2, 0 ) ]''' M = sage__eval( 'matrix( QQ,' + M + ')' ) D, V = M.eigenmatrix_right() # M*V==V*D assert M * V == V * D # M == V*D*~V == W.T*D*W == U.T*J*U # U == L*W and D == L.T*J*L W = sage_matrix( [col / col.norm() for col in V.columns()] ) # V.T normed L = sage_diagonal_matrix( [ d.abs().sqrt() for d in D.diagonal()] ) J = sage_diagonal_matrix( [ d / abs( d ) for d in D.diagonal()] ) U = L * W print( U.T * J * U ) out = approx_QQ( U.T * J * U ) print( out ) assert M == out
def test__imp_pmz(self): A = sage__eval( '[(1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 119/169, -120/169, 0), (0, 0, 120/169, 119/169, 0), (0, 0, 0, 0, 1)]' ) A = sage_matrix(A) B = sage_identity_matrix(5) baseA, baseB, pmzAB = get_pmz(A, B, 0) dct = get_imp(A, B, 0, False, False) key_lst = [ 'Agreat', 'Bgreat', 'eqn_x', 'eqn_str', 'eqn_xyz', 'sng_lst' ] Agreat, Bgreat, eqn_x, eqn_str, eqn_xyz, sng_lst = [ dct[key] for key in key_lst ] x, y, z = sage_var('x,y,z') seqn = eqn_xyz.subs({ x: pmzAB[0], y: pmzAB[1], z: pmzAB[2] }).simplify_trig() print(seqn) assert seqn == 0
def pov_coef_lst( poly ): ''' Parameters ---------- poly : string A string representing a polynomial in QQ[x,y,z]. Returns ------- tuple A 2-tuple (<degree poly>, <coefficient list of poly>) where the coefficient list is ordered according to povray's poly object: http://www.povray.org/documentation/3.7.0/r3_4.html#r3_4_5_3_2 ''' R = sage_PolynomialRing( sage_QQ, 'x,y,z', order = 'degrevlex' ) # lower degree equations first x, y, z = R.gens() poly = sage__eval( str( poly ), R.gens_dict() ) d = poly.total_degree() v = len( poly.variables() ) exp_lst = pov_exp_lst( d, v + 1 ) coef_lst = [] for exp in exp_lst: coef_lst += [ poly.coefficient( {x:exp[0], y:exp[1], z:exp[2]} ) ] return d, coef_lst
def get_deg_dim( imp_lst ): ''' Parameters ---------- imp_lst : list<OrbRing.R> A list of homogenous polynomials in QQ[x0,...,x8] representing a variety S in projective 8-space P^8. Returns ------- int[] A 2-tuple of integers consisting of the degree and the dimension of the variety S. ''' # consider ideal in ring of the right dimension. R = sage_PolynomialRing( sage_QQ, sage_var( 'y0,y1,y2,y3,y4,y5,y6,y7,y8' ), order = 'degrevlex' ) I = R.ideal( sage__eval( str( imp_lst ).replace( 'x', 'y' ), R.gens_dict() ) ) # compute Hilbert polynomial: (deg/dim!)*t^dim + ... hpol = I.hilbert_polynomial() dim = hpol.degree() deg = hpol for i in range( dim ): deg = deg.diff() OrbTools.p( 'hpol =', hpol, ' (deg, dim)=', ( deg, dim ) ) return deg, dim
def test__get_pmz(self): A = sage__eval( '[(1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 119/169, -120/169, 0), (0, 0, 120/169, 119/169, 0), (0, 0, 0, 0, 1)]' ) A = sage_matrix(A) B = sage_identity_matrix(5) baseA, baseB, pmzAB = get_pmz(A, B, 0) print(baseA) print(baseB) print(pmzAB) assert len(baseA) == 3 assert len(baseB) == 3 assert len(pmzAB) == 3
def get_rmat(r_str): ''' Parameters ---------- r_str : string A string with the following format 'R****[%,%,%,%]' where: *-symbol is a place holder for a character in ['r','s','m','p','a'] %-symbol denotes an integer in [0,360] Returns ------- sage_matrix A 9x9 matrix over "OrbRing.num_field" of the same shape as "get_omat( 'O****' )" The "c0" and "s0" in each block are substituted with a rational approximation of cos(%) and sin(%) respectively. ''' omat = get_omat('O' + r_str[1:5]) cs_lst = sage__eval(r_str[5:]) c0, s0 = OrbRing.coerce('c0,s0') rmat = [] idx = -1 dct = {} for row in list(omat): if idx % 2 == 0: cv, sv = get_cs(cs_lst[idx / 2]) dct = {c0: cv, s0: sv} if cv**2 + sv**2 != 1: raise Exception('Expect cos(%)^2+sin(%)^2=1.') idx = idx + 1 rrow = [] for col in row: rrow += [col.subs(dct)] rmat += [rrow] return sage_matrix(rmat)
def test__get_imp(self): A = sage__eval( '[(1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 119/169, -120/169, 0), (0, 0, 120/169, 119/169, 0), (0, 0, 0, 0, 1)]' ) A = sage_matrix(A) B = sage_identity_matrix(5) dct = get_imp(A, B, 0, False, False) key_lst = [ 'Agreat', 'Bgreat', 'eqn_x', 'eqn_str', 'eqn_xyz', 'sng_lst' ] Agreat, Bgreat, eqn_x, eqn_str, eqn_xyz, sng_lst = [ dct[key] for key in key_lst ] assert Agreat and Bgreat assert eqn_x.total_degree() == 4 assert sng_lst == []
def set_short_str( self, short_str ): ''' Parameters ---------- short_str : string A string of a list of length two. The first element is a string and the second element a dictionary with specifications as "self.info_dct". See also "OrbOutput.get_short_str()". Returns ------- self The attributes "self.info_dct", "self.omat", "self.vmat" and "self.pmat" are set according to parameter "short_str". ''' dct = sage__eval( short_str )[1] self.set( dct['pmat'], dct['omat'], dct['vmat'] ) return self
def get_emat(perm_str): ''' Parameters ---------- perm_str : string Either 'E' or a string with format: 'E[$,$,$,$,$,$,$,$]' where each integer $ in range(1,8+1) occurs exactly once. For example 'E[2,1,3,4,5,6,7,8]' is correct, but 'E[1,1,3,4,5,6,7,8]' is incorrect. Returns ------- sage_matrix A 9*9 permutation matrix over QQ such that the first row and column are: (1,0,0,0,0,0,0,0,0). If "perm_str=='E'", then a random permutation matrix is computed (the first coordinate is not permuted). Otherwise the returned matrix corresponds to the permutation: [0,1,2,3,4,5,6,7,8] ---> [0]+[$,$,$,$,$,$,$,$] ''' # # Permutations only permute list of the form [1,2,...] # so we add one to the elements of the input list # if perm_str[0] != 'E': raise ValueError('Incorrect perm_str: ', perm_str) elif perm_str == 'E': p = sage_Permutations(range(1, 8 + 1)) perm_lst = list(p.random_element()) else: perm_lst = sage__eval(perm_str[1:]) if len(perm_lst) != 8: raise ValueError('Incorrect perm_str (8 integers expected): ', perm_str) perm_lst = [1] + [perm + 1 for perm in perm_lst] return sage_Permutation(perm_lst).to_matrix().T
def set(self, short_input): ''' Convenience method for setting attributes of self. Parameters ---------- short_input : object A list or string of a list that has the following form [ [( a12, a13, a23 ), ( a14, a24, a34 ), ( u1, u2, u3 ), sa ], [( b12, b13, b23 ), ( b14, b24, b34 ), ( v1, v2, v3 ), sb ] ] See also SphereInput.__str__(). Returns ------- self The following attributes of self are set: rota, trna, sa, rotb, trnb, sb. ''' lsta, lstb = sage__eval(str(short_input)) a12, a13, a23, a14, a24, a34, u1, u2, u3, sa = sage_flatten(lsta) b12, b13, b23, b14, b24, b34, v1, v2, v3, sb = sage_flatten(lstb) # circle A self.rota = [a12, a13, a23, a14, a24, a34] self.trna = [u1, u2, u3] self.sa = sa # circle B self.rotb = [b12, b13, b23, b14, b24, b34] self.trnb = [v1, v2, v3] self.sb = sb return self
def test__random(self): coef_bnd = 3 in1 = OrbInput().random(3, False) print(in1) print(in1.info_dct['vmat'][0]) print(in1.info_dct['vmat'][2]) s = '' s += in1.info_dct['vmat'][0][1:] if in1.info_dct['vmat'][2] != 'I': s += '+' s += in1.info_dct['vmat'][2][1:] for elt in sage__eval(s): assert elt >= -coef_bnd and elt <= coef_bnd in2 = OrbInput().set(in1.info_dct['pmat'], in1.info_dct['omat'], in1.info_dct['vmat']) assert in1.pmat == in2.pmat assert in1.omat == in2.omat assert in1.vmat == in2.vmat
def get_xmat(r_str): ''' Parameters ---------- r_str : string A string of the following format: 'X[%,%,%]' where % denotes an integer in [0,360]. Returns ------- sage_matrix A matrix corresponding to the map S^7--->S^7 that is the composition of the following rotation matrices. Angle 1: [ 1 0 0 0 0 0 0 0 0] [ 0 c0 -s0 0 0 0 0 0 0] [ 0 s0 c0 0 0 0 0 0 0] [ 0 0 0 1 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0] [ 0 0 0 0 0 1 0 0 0] [ 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 1 0] [ 0 0 0 0 0 0 0 0 1] Angle 2: [ 1 0 0 0 0 0 0 0 0] [ 0 c0 0 -s0 0 0 0 0 0] [ 0 0 1 0 0 0 0 0 0] [ 0 s0 0 c0 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0] [ 0 0 0 0 0 1 0 0 0] [ 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 1 0] [ 0 0 0 0 0 0 0 0 1] Angle 3: [ 1 0 0 0 0 0 0 0 0] [ 0 1 0 0 0 0 0 0 0] [ 0 0 c0 -s0 0 0 0 0 0] [ 0 0 s0 c0 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0] [ 0 0 0 0 0 1 0 0 0] [ 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 1 0] [ 0 0 0 0 0 0 0 0 1] ''' # parse input string # if r_str[0] != 'X': raise ValueError('Incorrect format of input: ', r_str) r_lst = sage__eval(r_str[1:]) if len(r_lst) != 3: raise ValueError('Incorrect format of input: ', r_str) # mat1 # a_lst = [r_lst[0], 0, 0, 0] mat1 = get_rmat('Rrppp' + str(a_lst)) OrbTools.p('mat1 =\n' + str(get_omat('Orppp'))) # mat2 # a_lst = [r_lst[1], 0, 0, 0] e_lst = [1, 3, 2, 4, 5, 6, 7, 8] eI_lst = sage_Permutation(e_lst).inverse() m_tup = ('E' + str(eI_lst), 'Rrppp' + str(a_lst), 'E' + str(e_lst)) mat2 = get_mat(*m_tup) m_tup = ('E' + str(eI_lst), 'Orppp', 'E' + str(e_lst)) OrbTools.p('mat2 =\n' + str(get_mat(*m_tup))) # mat3 # a_lst = [0, r_lst[2], 0, 0] e_lst = [1, 4, 2, 3, 5, 6, 7, 8] eI_lst = sage_Permutation(e_lst).inverse() m_tup = ('E' + str(eI_lst), 'Rprpp' + str(a_lst), 'E' + str(e_lst)) mat3 = get_mat(*m_tup) m_tup = ('E' + str(eI_lst), 'Oprpp', 'E' + str(e_lst)) OrbTools.p('mat3 =\n' + str(get_mat(*m_tup))) return mat3 * mat2 * mat1
def get_tmat(t_str=None): ''' Parameters ---------- t_str : string A String with either one of the following 3 formats: * A string with format: 'T[#,#,#,#,#,#,#]' where # are in "OrbRing.num_field". * 'tT'. * "None". Returns ------- sage_matrix A 9x9 matrix defined over "OrbRing.num_field" representing an Euclidean translation of S^7. This map is obtained as the composition of a stereographic projection with center (1:0:0:0:0:0:0:0:1), an Euclidean translation in R^7, and the inverse stereographic projection. If "t_str==None", then the entries of the translation matrix are indeterminates t1,...,t7 in "OrbRing.R". If "t_str=='tT'", then the indeterminates are set to [c0,s0,0,0,0,0,0]. Thus the translations along a circle. ''' t = OrbRing.coerce('[t1,t2,t3,t4,t5,t6,t7]') # construct a translation matrix with undetermined # translations in t1,...,t7 a = (sage_QQ(1) / 2) * sum([ti**2 for ti in t]) mat = [] mat += [[1 + a] + list(t) + [-a]] for i in range(0, 7): mat += [[t[i]] + sage_identity_matrix(OrbRing.R, 7).row(i).list() + [-t[i]]] mat += [[a] + list(t) + [1 - a]] if t_str == None: # return matrix with indeterminates return sage_matrix(OrbRing.R, mat) elif t_str == 'tT': # translations along a circle c0, s0 = OrbRing.coerce('c0,s0') q = [c0, s0, 0, 0, 0, 0, 0] else: # Substitute coordinates [#,#,#,#,#,#,#] # for the t0,...,t7 variables. q = sage__eval(t_str[1:]) if len(q) != 7: raise ValueError('Expect 7 translation coordinates: ', t_str) # substitute q for t smat = [] for row in mat: srow = [] for col in row: srow += [col.subs({t[i]: q[i] for i in range(7)})] smat += [srow] if t_str == 'tT': return sage_matrix(OrbRing.R, smat) else: return sage_matrix(OrbRing.num_field, smat)
def get_sing_lst( pol, probable = True ): ''' The method requires that the magma-command is in "os.environ['PATH']". See [http://magma.maths.usyd.edu.au/magma/]. Parameters ---------- pol : OrbRing.R A homogeneous polynomial in QQ[x0,x1,x2,x3]. probable : boolean If True, performs a non-deterministic version of a radical decomposition algorithm, which is faster. The correctness of output is not guaranteed in this case. Returns ------- list Suppose that X is the surface defined by the zero-set of "pol". The output is a list [ (<I>, <H>), ... ] where <I> is the ideal of a component in singular locus of X, and <H> is the Hilbert polynomial of this ideal. If Magma is not accessible, then the empty-list [] is returned. ''' x0, x1, x2, x3 = OrbRing.coerce( 'x0,x1,x2,x3' ) df_str = str( [sage_diff( pol, x0 ), sage_diff( pol, x1 ), sage_diff( pol, x2 ), sage_diff( pol, x3 )] )[1:-1] OrbTools.p( df_str ) mi = '' mi += 'P<x0,x1,x2,x3> := PolynomialRing(RationalField(), 4);\n' mi += 'MI := ideal< P |' + df_str + '>;\n' if probable: mi += 'MD := ProbableRadicalDecomposition( MI );\n' else: mi += 'MD := RadicalDecomposition( MI );\n' mi += '#MD;\n' try: mo1 = int( sage_magma.eval( mi ) ) except: return [] sing_lst = [] Ry = sage_PolynomialRing( OrbRing.num_field, sage_var( 'y0,y1,y2,y3' ), order = 'degrevlex' ) for idx in range( mo1 ): comp = str( sage_magma.eval( 'Basis(MD[' + str( idx + 1 ) + ']);\n' ) ) comp = comp.replace( '\n', '' ) # compute hilbert polynomial of component in singular locus compy = sage__eval( comp.replace( 'x', 'y' ), Ry.gens_dict() ) idy = Ry.ideal( compy ) hpol = idy.hilbert_polynomial() sing_lst += [( comp, hpol )] OrbTools.p( idx, sing_lst[-1] ) OrbTools.p( sing_lst ) return sing_lst