def test__povray( self ): c0, s0, c1, s1 = sage_var( 'c0,s0,c1,s1' ) x, y, z = sage_var( 'x,y,z' ) r = 1 R = 2 pmz_AB_lst = [1, ( c0 * r + R ) * c1, ( c0 * r + R ) * s1, r * s0] f_xyz = ( x ** 2 + y ** 2 + z ** 2 + R ** 2 - r ** 2 ) ** 2 - 4 * R ** 2 * ( x ** 2 + y ** 2 ) v0_lst = [ ( sage_QQ( i ) / 180 ) * sage_pi for i in range( 0, 360, 150 )] v1_lst = [ ( sage_QQ( i ) / 180 ) * sage_pi for i in range( 0, 360, 300 )] # set PovInput as container # put very low quality for testing purposes pin = PovInput() pin.path = './' + get_time_str() + '_TEST_POVRAY_REMOVE_ME/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = ( 0, -7, 0 ) pin.cam_dct['lookat'] = ( 0, 0, 0 ) pin.cam_dct['rotate'] = ( 45, 0, 0 ) pin.light_radius = 5 pin.axes_dct['show'] = True pin.axes_dct['len'] = 3 pin.width = 2 pin.height = 2 pin.quality = 1 pin.ani_delay = 1 pin.impl = f_xyz pin.pmz_dct['A'] = ( pmz_AB_lst, 0 ) pin.pmz_dct['B'] = ( pmz_AB_lst, 1 ) pin.curve_dct['A'] = {'step0':v0_lst, 'step1': v1_lst, 'prec':1, 'width':0.08} pin.curve_dct['B'] = {'step0':v0_lst, 'step1': v1_lst, 'prec':1, 'width':0.08} pin.text_dct['A'] = [True, ( 0.5, 0.0, 0.0, 0.0 ), 'phong 0.2 phong_size 5' ] pin.text_dct['B'] = [True, ( 0.2, 0.3, 0.2, 0.0 ), 'phong 0.2 phong_size 5' ] pin.text_dct['SURF'] = [True, ( 0.2, 0.7, 0.3, 0.0 ), 'F_Glass10'] # raytrace image/animation show_surf = True ani = False ft_lst = [] lst = create_pov( pin, ['A', 'B'], show_surf, ani, ft_lst ) lst = create_pov( pin, ['A'], False, True, [] )
def test__get_prj_S3(self): x0, x1, x2, x3, x4 = sage_var('x0,x1,x2,x3,x4') v = sage_vector([x1, x2, x3, x4, x0]) out = get_prj_S3(v) print(out) assert out == [-x1 / (x0 - x4), -x2 / (x0 - x4), -x3 / (x0 - x4)]
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 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_hp_P4(self): c0, s0, c1, s1 = sage_var('c0,s0,c1,s1') v = sage_vector([1, c0, s0, 0, 0]) w = sage_vector([1, c1, s1, 0, 0]) a12, a13, a23, a14, a24, a34 = [90, 0, 0, 0, 0, 0] M = get_rot_S3([a12, a13, a23, a14, a24, a34]) out = get_hp_P4(v, M * w) print(out) assert str(out) == '[1, -c1*s0 - c0*s1, c0*c1 - s0*s1, 0, 0]'
def test__get_hp_S3(self): a01, a02, a03, a12, a13, a23 = 5 * [0] + [2] M = get_rot_S3(a01, a02, a03, a12, a13, a23) c0, s0, c1, s1 = sage_var('c0,s0,c1,s1') v = sage_vector([c0, s0, 0, 0, 1]) w = sage_vector([c1, s1, 0, 0, 1]) out = get_hp_S3(v, M * w) print(out) assert str(out) == '(c0*c1 - s0*s1, c1*s0 + c0*s1, 0, 0, 1)'
def get_pmz(A, B, prj): ''' Computes parametrization of a stereographic projection of the pointwise Hamiltonian product of circles in the sphere S^3 defined by transformations of the standard circle [1,cos(a),sin(a),0,0] by A and B respectively. Parameters ---------- A : sage_Matrix<sage_QQ> Represents a linear transformation S^3--->S^3 B : sage_Matrix<sage_QQ> Represents a linear transformation S^3--->S^3 prj : int Choice for stereographic projection S^3--->P^3: 0: (x0:x1:x2:x3:x4) |--> (x0-x4:x1:x2:x3) 1: (x0:x1:x2:x3:x4) |--> (x0-x1:x4:x2:x3) 2: (x0:x1:x2:x3:x4) |--> (x0-x2:x1:x4:x3) 3: (x0:x1:x2:x3:x4) |--> (x0-x3:x1:x2:x4) Returns ------- tuple Returns tuple (baseA, baseB, pmzAB) where * baseA: Parametrization of projection of A in cos(a) and sin(a). * baseB: Parametrization of projection of B in cos(b) and sin(b). * pmzAB: Parametrization of projection of A*B. ''' dct = {} # Hamiltonian product of circles a, b = sage_var('a,b') u = list(A * sage_vector([1, sage_cos(a), sage_sin(a), 0, 0])) v = list(B * sage_vector([1, sage_cos(b), sage_sin(b), 0, 0])) p = get_hp_P4(u, v) # stereographic projection if prj == 0: j, i_lst = 4, [1, 2, 3] if prj == 1: j, i_lst = 1, [4, 2, 3] if prj == 2: j, i_lst = 2, [1, 4, 3] if prj == 3: j, i_lst = 3, [1, 2, 4] p = [p[i] / (p[0] - p[j]) for i in i_lst] # put in dictionary pmzAB = [elt.full_simplify() for elt in p] baseA = [u[i] / (u[0] - u[j]) for i in i_lst] baseB = [v[i] / (v[0] - v[j]) for i in i_lst] return baseA, baseB, pmzAB
def clifford(sinp): ''' Parameters ---------- sinp : SphereInput Returns ------- tuple A tuple (plt,out) where * plt : sage_Graphics object with plots of surface defined by "sinp". * out : Information string. Notes ----- See documentation at top of this file for possible usage of this method. ''' # # compute matrices A and B # T = get_trn_S3(sinp.trna) R = get_rot_S3(sinp.rota) S = get_scale_S3(sinp.sa) A = S * R * T T = get_trn_S3(sinp.trnb) R = get_rot_S3(sinp.rotb) S = get_scale_S3(sinp.sb) B = S * R * T # # Compute implicit and parametric form of a stereographic # projection of the Hamiltonian product of A and B. # baseA, baseB, pmzAB = get_pmz(A, B, sinp.prj) if sinp.imp: dct = get_imp(A, B, sinp.prj, sinp.sng, sinp.snp) 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 ] # # create graphics object # plt = sage_Graphics() a, b = sage_var('a,b') if sinp.pmz: plt += sage_parametric_plot3d(pmzAB, (a, 0, 2 * sage_pi), (b, 0, 2 * sage_pi), color=sinp.col_pmz, aspect_ratio=1, plot_points=sinp.ppt, opacity=sinp.opa) if sinp.bas: plt += sage_parametric_plot3d(baseA, (a, 0, 2 * sage_pi), color=sinp.col_famA, thickness=10, aspect_ratio=1) plt += sage_parametric_plot3d(baseB, (b, 0, 2 * sage_pi), color=sinp.col_famB, thickness=10, aspect_ratio=1) if sinp.mrk: plt += sage_point3d((0, 0, 0), size=30, color=sage_Color("magenta")) plt += sage_point3d((1, 0, 0), size=30, color=sage_Color("green")) if sinp.fam: if sinp.famA: for b1 in range(0, 360, sinp.stp): ps = [ pmzAB[i].subs({b: b1 * sage_pi / 180}) for i in [0, 1, 2] ] plt += sage_parametric_plot3d(ps, (a, 0, 2 * sage_pi), color=sage_Color("red"), thickness=sinp.famt, aspect_ratio=1, plot_points=sinp.ppt) if sinp.famB: for a1 in range(0, 360, sinp.stp): ps = [ pmzAB[i].subs({a: a1 * sage_pi / 180}) for i in [0, 1, 2] ] plt += sage_parametric_plot3d(ps, (b, 0, 2 * sage_pi), color=sage_Color("blue"), thickness=sinp.famt, aspect_ratio=1, plot_points=sinp.ppt) if sinp.imp: rng = sinp.rng x, y, z = sage_var('x,y,z') plt += sage_implicit_plot3d(eqn_xyz, (x, -rng, rng), (y, -rng, rng), (z, -rng, rng), color=sinp.col_imp, plot_points=sinp.ppt, opacity=sinp.opa) # # create output string # out = '' out += str(sinp) out += '\n' if sinp.imp: out += '\neqn_str = ' + eqn_str out += '\nAgreat = ' + str(Agreat) out += '\nBgreat = ' + str(Bgreat) out += '\nA = ' + str(list(A)) out += '\nB = ' + str(list(B)) out += '\npmzAB = ' + str(pmzAB) if sinp.sng: out += '\nsng_lst (long) =' out += '\n-----' for sng in sng_lst: out += '\n' + str(sng) out += '\n-----' out += '\nsng_lst (short) =' out += '\n-----' for sng in sng_lst: out += '\n' + str(sng[1]) out += '\n-----' return plt, out
def veronese(): ''' Construct povray image of a 3-web of conics on the Veronese surface. ''' ############################################# # Construct projection of Veronese surface. # ############################################# c0, s0, c1, s1, t0 = sage_var('c0,s0,c1,s1,t0') x, y = sage_var('x,y') pmz_A_lst = [1, c0 * s0 * s1, c0 * s0 * c1, c0 * c0 * c1 * s1] P1 = c0 / (s0 - 1) P2 = c1 / (s1 - 1) P3 = (s0 / c0) * (c1 / (s1 - 1)) dct_CD = {x: P1, y: P2} den_CD = (s0 - 1)**2 * (s1 - 1)**2 dct_ED = {x: P3, y: P2} den_ED = c0**2 * (s1 - 1)**2 pmz_lst = [x**2 + y**2 + 1, -x, -x * y, y] pmz_B_lst = [(pmz.subs(dct_CD) * den_CD).expand() for pmz in pmz_lst] pmz_C_lst = [(pmz.subs(dct_ED) * den_ED).expand() for pmz in pmz_lst] # parametrization of circles # pmz_C1_lst = [pmz.subs({x: t0, y: -t0 - 1}) for pmz in pmz_lst] pmz_C2_lst = [pmz.subs({x: t0, y: -t0 + 1}) for pmz in pmz_lst] pmz_C3_lst = [pmz.subs({x: t0, y: t0 + 1}) for pmz in pmz_lst] pmz_C4_lst = [pmz.subs({x: t0, y: t0 - 1}) for pmz in pmz_lst] # output # lst_lst = [('A', pmz_A_lst), ('B', pmz_B_lst), ('C', pmz_C_lst)] lst_lst += [ ('C1', pmz_C1_lst), ('C2', pmz_C2_lst), ('C3', pmz_C3_lst), ('C4', pmz_C4_lst), ] for A, pmz_lst in lst_lst: OrbTools.p('pmz_' + A + '_lst =', pmz_lst) for pmz in pmz_lst: OrbTools.p('\t\t', sage_factor(pmz)) ############################# # PovInput Veronese surface # ############################# pin = PovInput() pin.path = './' + get_time_str() + '_veronese/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = (0, -1.2, 0) pin.cam_dct['lookat'] = (0, 0, 0) pin.cam_dct['rotate'] = (35, 0, 45) pin.shadow = True pin.light_lst = [(0, 0, -5), (0, -5, 0), (-5, 0, 0), (0, 0, 5), (0, 5, 0), (5, 0, 0)] pin.axes_dct['show'] = False pin.axes_dct['len'] = 0.5 pin.height = 400 pin.width = 800 pin.quality = 11 pin.ani_delay = 10 pin.impl = None pin.pmz_dct['A'] = (pmz_A_lst, 0) pin.pmz_dct['B'] = (pmz_B_lst, 1) pin.pmz_dct['C'] = (pmz_C_lst, 1) pin.pmz_dct['FA'] = (pmz_A_lst, 0) pin.pmz_dct['FB'] = (pmz_B_lst, 1) pin.pmz_dct['FC'] = (pmz_C_lst, 1) pin.pmz_dct['FA2'] = (pmz_A_lst, 0) pin.pmz_dct['FB2'] = (pmz_B_lst, 1) pin.pmz_dct['FC2'] = (pmz_C_lst, 1) pin.pmz_dct['C1'] = (pmz_C1_lst, 0) pin.pmz_dct['C2'] = (pmz_C2_lst, 0) pin.pmz_dct['C3'] = (pmz_C3_lst, 0) pin.pmz_dct['C4'] = (pmz_C4_lst, 0) v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 5)] v1_A_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 9)] v1_B_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 18)] v1_C_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 9)] v1_lst_F = [(sage_QQ(i) / (3 * 180)) * sage_pi for i in range(0, 3 * 360, 1)] v1_lst_F2 = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 2)] v0_lst_CC = [sage_QQ(i) / 10 for i in range(-100, 100, 1)] prec = 50 pin.curve_dct['A'] = { 'step0': v0_lst, 'step1': v1_A_lst, 'prec': prec, 'width': 0.01 } pin.curve_dct['B'] = { 'step0': v0_lst, 'step1': v1_B_lst, 'prec': prec, 'width': 0.01 } pin.curve_dct['C'] = { 'step0': v0_lst, 'step1': v1_C_lst, 'prec': prec, 'width': 0.01 } pin.curve_dct['FA'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.001 } pin.curve_dct['FB'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.001 } pin.curve_dct['FC'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.001 } pin.curve_dct['FA2'] = { 'step0': v0_lst, 'step1': v1_lst_F2, 'prec': prec, 'width': 0.001 } pin.curve_dct['FB2'] = { 'step0': v0_lst, 'step1': v1_lst_F2, 'prec': prec, 'width': 0.001 } pin.curve_dct['FC2'] = { 'step0': v0_lst, 'step1': v1_lst_F2, 'prec': prec, 'width': 0.001 } pin.curve_dct['C1'] = { 'step0': v0_lst_CC, 'step1': [0], 'prec': prec, 'width': 0.01 } pin.curve_dct['C2'] = { 'step0': v0_lst_CC, 'step1': [0], 'prec': prec, 'width': 0.01 } pin.curve_dct['C3'] = { 'step0': v0_lst_CC, 'step1': [0], 'prec': prec, 'width': 0.01 } pin.curve_dct['C4'] = { 'step0': v0_lst_CC, 'step1': [0], 'prec': prec, 'width': 0.01 } col_A = (0.6, 0.4, 0.1, 0.0) col_B = (0.1, 0.15, 0.0, 0.0) col_C = (0.2, 0.3, 0.2, 0.0) colFF = (0.1, 0.1, 0.1, 0.0) colCC = (0.6, 0.0, 0.0, 0.0) pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5'] pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FA2'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB2'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FC2'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['C1'] = [True, colCC, 'phong 0.2 phong_size 5'] pin.text_dct['C2'] = [True, colCC, 'phong 0.2 phong_size 5'] pin.text_dct['C3'] = [True, colCC, 'phong 0.2 phong_size 5'] pin.text_dct['C4'] = [True, colCC, 'phong 0.2 phong_size 5'] ############################ # raytrace image/animation # ############################ # four circles on projection Veronese surface pin.cam_dct['location'] = (0, -1.5, 0) pin.cam_dct['rotate'] = (60, 10, 45) create_pov(pin, ['FA2', 'FB2', 'FC2']) create_pov(pin, ['C1', 'C2', 'C3', 'C4'] + ['FA2', 'FB2', 'FC2']) # hexagonal web on Veronese surface pin.cam_dct['location'] = (0, -1.2, 0) pin.cam_dct['rotate'] = (35, 0, 45) create_pov(pin, ['A', 'B', 'C']) create_pov(pin, ['A', 'B', 'C', 'FA', 'FB', 'FC']) create_pov(pin, ['FA2', 'FB2', 'FC2'])
def CH1_cyclide(): ''' Creates povray image of a CH1 cyclide, which is an inversion of a Circular Hyperboloid of 1 sheet. ''' # Construct a trigonometric parametrization by rotating a circle. r, R = 1, 1 c0, s0, c1, s1 = sage_var('c0,s0,c1,s1') x, y, v, w, a0 = sage_var('x,y,v,w,a0') q2 = sage_QQ(1) / 2 MX = sage_matrix([(1, 0, 0), (0, c1, s1), (0, -s1, c1)]) MXc = MX.subs({c1: a0, s1: a0}) # a0=1/sqrt(2)=cos(pi/4)=sin(pi/4) MZ = sage_matrix([(c1, s1, 0), (-s1, c1, 0), (0, 0, 1)]) V = sage_vector([r * c0, 0, r * s0]) V = MXc * V V[0] = V[0] + R pmz_AB_lst = list(MZ * V) OrbTools.p('V =', V) OrbTools.p('pmz_AB_lst =', pmz_AB_lst) for pmz in pmz_AB_lst: OrbTools.p('\t\t', sage_factor(pmz)) # Convert the trigonometric parametrization to a rational parametrization # We convert via the following formulas, # # cos(s) = (y^2-x^2) / (y^2+x^2) # sin(s) = 2*x*y / (y^2+x^2) # y=1; x = arctan( s/2 ) # C0 = (y**2 - x**2) / (y**2 + x**2) S0 = 2 * x * y / (y**2 + x**2) C1 = (w**2 - v**2) / (w**2 + v**2) S1 = 2 * v * w / (w**2 + v**2) den = (y**2 + x**2) * (w**2 + v**2) dct = {c0: C0, s0: S0, c1: C1, s1: S1} pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full() for elt in list(MZ * V)] OrbTools.p('pmz_lst =', pmz_lst) for pmz in pmz_lst: OrbTools.p('\t\t', sage_factor(pmz)) # do a basepoint analysis on the rational parametrization # The True argument is for resetting the number field to QQ! ring = PolyRing('x,y,v,w', True).ext_num_field('t^2-1/2') ls = LinearSeries([str(pmz) for pmz in pmz_lst], ring) OrbTools.p(ls.get_bp_tree()) # construct linear series for families of conics ring = PolyRing( 'x,y,v,w') # construct polynomial ring over new ground field OrbTools.p(ring) x, y, v, w = ring.gens() a0, a1 = ring.root_gens() p1 = ['xv', (0, 2 * a0 * a1)] p2 = ['xv', (0, -2 * a0 * a1)] p3 = ['xv', (a1, 2 * a0 * a1)] p4 = ['xv', (-a1, -2 * a0 * a1)] bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_1234.add(p1[0], p1[1], 1) bpt_1234.add(p2[0], p2[1], 1) bpt_1234.add(p3[0], p3[1], 1) bpt_1234.add(p4[0], p4[1], 1) bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_12.add(p1[0], p1[1], 1) bpt_12.add(p2[0], p2[1], 1) bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_34.add(p3[0], p3[1], 1) bpt_34.add(p4[0], p4[1], 1) ls_22 = LinearSeries.get([2, 2], bpt_1234) # |2(l1+l2)-e1-e2-e3-e4| ls_21 = LinearSeries.get([2, 1], bpt_1234) ls_12 = LinearSeries.get([1, 2], bpt_1234) ls_11a = LinearSeries.get([1, 1], bpt_12) ls_11b = LinearSeries.get([1, 1], bpt_34) OrbTools.p('linear series 22 =\n', ls_22) OrbTools.p('linear series 21 =\n', ls_21) OrbTools.p('linear series 12 =\n', ls_12) OrbTools.p('linear series 11a =\n', ls_11a) OrbTools.p('linear series 11b =\n', ls_11b) # compute reparametrization from the linear series of families ring = PolyRing( 'x,y,v,w,c0,s0,c1,s1') # construct polynomial ring with new generators OrbTools.p(ring) x, y, v, w, c0, s0, c1, s1 = ring.gens() a0, a1 = ring.root_gens() pmz_AB_lst = [1] + ring.coerce(pmz_AB_lst) pmz_lst = ring.coerce(pmz_lst) X = 1 - s0 Y = c0 V = 1 - s1 W = c1 CB_dct = { x: X, y: Y, v: W * X - 2 * a0 * V * Y, w: V * X + 2 * a0 * W * Y } pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst] # CB 11b # output OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst) OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst) # approximate by map defined over rational numbers ci_idx = 0 # index defining the complex embedding OrbTools.p('complex embeddings =') for i in range(len(a0.complex_embeddings())): a0q = OrbRing.approx_QQ_coef(a0, i) OrbTools.p('\t\t' + str(i) + ' =', a0q, sage_n(a0q)) pmz_AB_lst = OrbRing.approx_QQ_pol_lst(pmz_AB_lst, ci_idx) pmz_CB_lst = OrbRing.approx_QQ_pol_lst(pmz_CB_lst, ci_idx) # mathematica input ms = '' for pmz, AB in [(pmz_lst, 'ZZ'), (pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB')]: s = 'pmz' + AB + '=' + str(pmz) + ';' s = s.replace('[', '{').replace(']', '}') ms += '\n' + s OrbTools.p('Mathematica input =', ms) # PovInput ring cyclide # pin = PovInput() pin.path = './' + get_time_str() + '_CH1_cyclide/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = (0, -5, 0) pin.cam_dct['lookat'] = (0, 0, 0) pin.cam_dct['rotate'] = (20, 0, 0) pin.shadow = True pin.light_lst = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0), (0, -1, 0), (0, 0, -1), (10, 0, 0), (0, 10, 0), (0, 0, 10), (-10, 0, 0), (0, -10, 0), (0, 0, -10)] pin.axes_dct['show'] = False pin.axes_dct['len'] = 1.2 pin.height = 400 pin.width = 800 pin.quality = 11 pin.ani_delay = 10 pin.impl = None pin.pmz_dct['A'] = (pmz_AB_lst, 0) pin.pmz_dct['B'] = (pmz_AB_lst, 1) pin.pmz_dct['C'] = (pmz_CB_lst, 0) pin.pmz_dct['FA'] = (pmz_AB_lst, 0) pin.pmz_dct['FB'] = (pmz_AB_lst, 1) pin.pmz_dct['FC'] = (pmz_CB_lst, 0) v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] v1_lst_A = [(sage_QQ(i) / 180) * sage_pi for i in range(180, 360, 10)] v1_lst_B = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 10)] v1_lst_C = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 10)] v1_lst_FA = [(sage_QQ(i) / 180) * sage_pi for i in range(180, 360, 2)] v1_lst_FB = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 2)] v1_lst_FC = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 2)] prec = 50 pin.curve_dct['A'] = { 'step0': v0_lst, 'step1': v1_lst_A, 'prec': prec, 'width': 0.03 } pin.curve_dct['B'] = { 'step0': v0_lst, 'step1': v1_lst_B, 'prec': prec, 'width': 0.03 } pin.curve_dct['C'] = { 'step0': v0_lst, 'step1': v1_lst_C, 'prec': prec, 'width': 0.03 } pin.curve_dct['FA'] = { 'step0': v0_lst, 'step1': v1_lst_FA, 'prec': prec, 'width': 0.02 } pin.curve_dct['FB'] = { 'step0': v0_lst, 'step1': v1_lst_FB, 'prec': prec, 'width': 0.02 } pin.curve_dct['FC'] = { 'step0': v0_lst, 'step1': v1_lst_FC, 'prec': prec, 'width': 0.02 } col_A = (0.6, 0.4, 0.1, 0.0) col_B = (0.1, 0.15, 0.0, 0.0) col_C = (0.2, 0.3, 0.2, 0.0) colFF = (0.1, 0.1, 0.1, 0.0) pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5'] pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5'] # raytrace image/animation create_pov(pin, ['A', 'B', 'C']) create_pov(pin, ['A', 'B', 'C', 'FA', 'FB', 'FC']) create_pov(pin, ['A', 'B', 'FA', 'FB']) create_pov(pin, ['B', 'C', 'FA', 'FB'])
def get_orb_bp_tree( pmz_lst ): ''' Parameters ---------- pmz_lst : list A list of 9 elements p0,...,p8 in QQ[c0,s0,c1,s1] such that -p0^2+p1^2+...+p8^2==0. Some of the polynomials can be equal to zero. The list should represent a parametrization: S^1xS^1--->S^7. Here (c0,s0) is a points on S^1 such that thus c0^2+s0^2-1==0. Similarly for (c1,s1). Returns ------- linear_series.BasePointTree Base points of a parametrizing map given by the composition: P^1xP^1---->S^1xS^1--->S^7--->S^n with 2<=n<=7. The composition of the latter two maps are defined by omitting the zero polynomials from "pmz_lst". ''' # setup dictionary for reparametrization' # c0, s0, c1, s1 = OrbRing.coerce( 'c0,s0,c1,s1' ) dct1 = {} dct1[c0] = '2*t0*t1/(t0^2+t1^2)' dct1[s0] = '(-t0^2+t1^2)/(t0^2+t1^2)' dct1[c1] = '2*v0*v1/(v0^2+v1^2)' dct1[s1] = '(-v0^2+v1^2)/(v0^2+v1^2)' for key in dct1: dct1[key] = OrbRing.coerce( dct1[key] ) # apply reparametrization and multiply out denominators # where we only consider non-zero entries # ps_lst = [ pmz for pmz in pmz_lst if pmz != 0 ] gcm1 = OrbRing.coerce( '(t0^2+t1^2)*(v0^2+v1^2)' ) ps_lst = [ OrbRing.coerce( ps.subs( dct1 ) * gcm1 ) for ps in ps_lst ] # ensure that polynomials are co-prime # gcd1 = sage_gcd( ps_lst ) ps_lst = [ OrbRing.coerce( ps / gcd1 ) for ps in ps_lst ] OrbTools.p( 'gcd =', gcd1 ) OrbTools.p( 'ps_lst =', ps_lst ) # Verify whether "ps_lst" represents a map P^1xP^1--->S^n # where "n==len(ps_lst)". # sum1 = sum( [-ps_lst[0] ** 2] + [ ps ** 2 for ps in ps_lst[1:] ] ) OrbTools.p( 'sum =', sum1 ) if sum1 != 0: warnings.warn( 'Warning: Not parametrization of surface in S^7: ' + str( sum1 ), ) # set coordinates x,y,v,w # t0, t1, v0, v1 = OrbRing.coerce( 't0,t1,v0,v1' ) dct2 = {} dct2[t0] = sage_var( 'x' ) dct2[t1] = sage_var( 'y' ) dct2[v0] = sage_var( 'v' ) dct2[v1] = sage_var( 'w' ) xyvw_lst = [ str( ps.subs( dct2 ) ) for ps in ps_lst ] # # Compute base point tree using "linear_series" package # ls = LinearSeries( xyvw_lst, PolyRing( 'x,y,v,w', True ) ) bp_tree = ls.get_bp_tree() OrbTools.p( ls ) OrbTools.p( bp_tree ) return bp_tree
def perseus_cyclide(): ''' Creates povray image of the Perseus cyclide. ''' # We first construct a trigonometric parametrization # by rotating a circle. # cos(pi/3) = 1/2 # sin(pi/3) = sqrt(3)/2 # r, R = 1, 2 c0, s0, c1, s1 = sage_var('c0,s0,c1,s1') x, y, v, w, a0 = sage_var('x,y,v,w,a0') q2 = sage_QQ(1) / 2 MZ = sage_matrix([(c1, s1, 0), (-s1, c1, 0), (0, 0, 1)]) MZc = MZ.subs({c1: q2, s1: q2 * a0}) V = sage_vector([r * c0, 0, r * s0]) V = MZc * V V[0] = V[0] + R pmz_AB_lst = list(MZ * V) OrbTools.p('V =', V) OrbTools.p('pmz_AB_lst =', pmz_AB_lst) for pmz in pmz_AB_lst: OrbTools.p('\t\t', sage_factor(pmz)) # We convert the trigonometric parametrization to a # rational parametrization, via the following formulas: # # cos(s) = (y^2-x^2) / (y^2+x^2) # sin(s) = 2*x*y / (y^2+x^2) # y=1; x = arctan( s/2 ) # C0 = (y**2 - x**2) / (y**2 + x**2) S0 = 2 * x * y / (y**2 + x**2) C1 = (w**2 - v**2) / (w**2 + v**2) S1 = 2 * v * w / (w**2 + v**2) den = (y**2 + x**2) * (w**2 + v**2) dct = {c0: C0, s0: S0, c1: C1, s1: S1} pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full() for elt in list(MZ * V)] OrbTools.p('pmz_lst =', pmz_lst) for pmz in pmz_lst: OrbTools.p('\t\t', sage_factor(pmz)) # do a basepoint analysis on the rational parametrization # ring = PolyRing('x,y,v,w', True).ext_num_field('t^2-3') ls = LinearSeries([str(pmz) for pmz in pmz_lst], ring) OrbTools.p(ls.get_bp_tree()) # construct linear series for families of conics # ring = PolyRing( 'x,y,v,w') # construct polynomial ring over new ground field OrbTools.p(ring) x, y, v, w = ring.gens() a0, a1, a2, a3 = ring.root_gens() p1 = ['xv', (-a3, a1)] p2 = ['xv', (-a2, -a1)] p3 = ['xv', (a3, a1)] p4 = ['xv', (a2, -a1)] bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_1234.add(p1[0], p1[1], 1) bpt_1234.add(p2[0], p2[1], 1) bpt_1234.add(p3[0], p3[1], 1) bpt_1234.add(p4[0], p4[1], 1) bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_12.add(p1[0], p1[1], 1) bpt_12.add(p2[0], p2[1], 1) bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_34.add(p3[0], p3[1], 1) bpt_34.add(p4[0], p4[1], 1) ls_22 = LinearSeries.get([2, 2], bpt_1234) ls_21 = LinearSeries.get([2, 1], bpt_1234) ls_12 = LinearSeries.get([1, 2], bpt_1234) ls_11a = LinearSeries.get([1, 1], bpt_12) ls_11b = LinearSeries.get([1, 1], bpt_34) OrbTools.p('linear series 22 =\n', ls_22) OrbTools.p('linear series 21 =\n', ls_21) OrbTools.p('linear series 12 =\n', ls_12) OrbTools.p('linear series 11a =\n', ls_11a) OrbTools.p('linear series 11b =\n', ls_11b) # compute reparametrization from the linear series of families ring = PolyRing('x,y,v,w,c0,s0,c1,s1') OrbTools.p(ring) x, y, v, w, c0, s0, c1, s1 = ring.gens() a0, a1, a2, a3 = ring.root_gens() pmz_AB_lst = [1] + ring.coerce(pmz_AB_lst) pmz_lst = ring.coerce(pmz_lst) q2 = sage_QQ(1) / 2 a = 2 * a0 / 3 b = (-a0 * a1 / 3 - q2) * a3 c = (a0 * a1 / 3 - q2) * a2 d = (a1 / 2 - a0 / 3) * a3 e = (-a1 / 2 - a0 / 3) * a2 bc = b + c de = d + e X = 1 - s0 Y = c0 V = 1 - s1 W = c1 CB_dct = { x: X, y: Y, v: W * X + bc * W * Y - de * V * Y, w: V * X + bc * V * Y + de * W * Y } DB_dct = { x: X, y: Y, v: W * X - bc * W * Y + de * V * Y, w: V * X - bc * V * Y - de * W * Y } EB_dct = { x: X, y: Y, v: W * X**2 + W * Y**2 - a * V * Y**2, w: V * X**2 + V * Y**2 + a * W * Y**2 } pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst] # CB 11a pmz_DB_lst = [pmz.subs(DB_dct) for pmz in pmz_lst] # CB 11b pmz_EB_lst = [pmz.subs(EB_dct) for pmz in pmz_lst] # CB 21 # output OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst) OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst) OrbTools.p('pmz_DB_lst =\n', pmz_DB_lst) OrbTools.p('pmz_EB_lst =\n', pmz_EB_lst) # approximate by map defined over rational numbers ci_idx = 5 # index defining the complex embedding pmz_AB_lst = OrbRing.approx_QQ_pol_lst(pmz_AB_lst, ci_idx) pmz_CB_lst = OrbRing.approx_QQ_pol_lst(pmz_CB_lst, ci_idx) pmz_DB_lst = OrbRing.approx_QQ_pol_lst(pmz_DB_lst, ci_idx) pmz_EB_lst = OrbRing.approx_QQ_pol_lst(pmz_EB_lst, ci_idx) # mathematica input ms = '' for pmz, AB in [(pmz_lst, 'ZZ'), (pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB'), (pmz_DB_lst, 'DB'), (pmz_EB_lst, 'EB')]: s = 'pmz' + AB + '=' + str(pmz) + ';' s = s.replace('[', '{').replace(']', '}') ms += '\n' + s OrbTools.p('Mathematica input =', ms) # PovInput ring cyclide # pin = PovInput() pin.path = './' + get_time_str() + '_perseus_cyclide/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = (0, 7, 0) pin.cam_dct['lookat'] = (0, 0, 0) pin.cam_dct['rotate'] = (45, 0, 0) pin.shadow = True pin.light_lst = [(0, 0, -10), (0, -10, 0), (-10, 0, 0), (0, 0, 10), (0, 10, 0), (10, 0, 0)] pin.axes_dct['show'] = False pin.axes_dct['len'] = 1.2 pin.height = 400 pin.width = 800 pin.quality = 11 pin.ani_delay = 10 pin.impl = None pin.pmz_dct['A'] = (pmz_AB_lst, 0) pin.pmz_dct['B'] = (pmz_AB_lst, 1) pin.pmz_dct['C'] = (pmz_CB_lst, 0) pin.pmz_dct['D'] = (pmz_DB_lst, 0) pin.pmz_dct['E'] = (pmz_EB_lst, 0) pin.pmz_dct['FA'] = (pmz_AB_lst, 0) pin.pmz_dct['FB'] = (pmz_AB_lst, 1) pin.pmz_dct['FC'] = (pmz_CB_lst, 0) pin.pmz_dct['FD'] = (pmz_DB_lst, 0) pin.pmz_dct['FE'] = (pmz_EB_lst, 0) v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] v1_lst_A = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] # 5 v1_lst_B = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 15)] v1_lst_C = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 36)] v1_lst_D = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 36)] v1_lst_E = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] # 5 v1_lst_F = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 1)] prec = 50 pin.curve_dct['A'] = { 'step0': v0_lst, 'step1': v1_lst_A, 'prec': prec, 'width': 0.04 } pin.curve_dct['B'] = { 'step0': v0_lst, 'step1': v1_lst_B, 'prec': prec, 'width': 0.04 } pin.curve_dct['C'] = { 'step0': v0_lst, 'step1': v1_lst_C, 'prec': prec, 'width': 0.05 } pin.curve_dct['D'] = { 'step0': v0_lst, 'step1': v1_lst_D, 'prec': prec, 'width': 0.05 } pin.curve_dct['E'] = { 'step0': v0_lst, 'step1': v1_lst_E, 'prec': prec, 'width': 0.04 } pin.curve_dct['FA'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.01 } pin.curve_dct['FB'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.01 } pin.curve_dct['FC'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.01 } pin.curve_dct['FD'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.01 } pin.curve_dct['FE'] = { 'step0': v0_lst, 'step1': v1_lst_F, 'prec': prec, 'width': 0.01 } col_A = (0.6, 0.0, 0.0, 0.0) # red col_B = (0.8, 0.6, 0.2, 0.0) # beige col_C = (0.6, 0.0, 0.0, 0.0 ) # red *** rgbt2pov( ( 74, 33, 0, 0 ) ) # brown col_D = (0.2, 0.6, 0.0, 0.0 ) # green *** rgbt2pov( ( 28, 125, 154, 0 ) ) # blue col_E = (0.2, 0.6, 0.0, 0.0) # green colFF = (0.1, 0.1, 0.1, 0.0) pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5'] pin.text_dct['D'] = [True, col_D, 'phong 0.2 phong_size 5'] pin.text_dct['E'] = [True, col_E, 'phong 0.2 phong_size 5'] pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FD'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FE'] = [True, colFF, 'phong 0.2 phong_size 5'] # raytrace image/animation create_pov(pin, ['C', 'D', 'FC', 'FD']) create_pov(pin, ['A', 'B', 'FC', 'FD']) create_pov(pin, ['E', 'B', 'FC', 'FD'])
def blum_cyclide(): ''' Construct a povray image of 6 families of circles on a smooth Darboux cyclide. This surface is also known as the Blum cyclide. ''' # construct dct a0 = PolyRing( 'x,y,v,w', True ).ext_num_field( 't^2 + 1' ).root_gens()[0] # i bpt_1234 = BasePointTree( ['xv', 'xw', 'yv', 'yw'] ) bpt_1234.add( 'xv', ( -1 * a0, 1 * a0 ), 1 ) # e1 bpt_1234.add( 'xv', ( 1 * a0, -1 * a0 ), 1 ) # e2 bpt_1234.add( 'xw', ( -2 * a0, 2 * a0 ), 1 ) # e3 bpt_1234.add( 'xw', ( 2 * a0, -2 * a0 ), 1 ) # e4 bpt_12 = BasePointTree( ['xv', 'xw', 'yv', 'yw'] ) bpt_12.add( 'xv', ( -1 * a0, 1 * a0 ), 1 ) # e1 bpt_12.add( 'xv', ( 1 * a0, -1 * a0 ), 1 ) # e2 bpt_34 = BasePointTree( ['xv', 'xw', 'yv', 'yw'] ) bpt_34.add( 'xw', ( -2 * a0, 2 * a0 ), 1 ) # e3 bpt_34.add( 'xw', ( 2 * a0, -2 * a0 ), 1 ) # e4 ls_22 = LinearSeries.get( [2, 2], bpt_1234 ) # |2(l1+l2)-e1-e2-e3-e4| ls_21 = LinearSeries.get( [2, 1], bpt_1234 ) ls_12 = LinearSeries.get( [1, 2], bpt_1234 ) ls_11a = LinearSeries.get( [1, 1], bpt_12 ) ls_11b = LinearSeries.get( [1, 1], bpt_34 ) OrbTools.p( 'linear series 22 =\n', ls_22 ) OrbTools.p( 'linear series 21 =\n', ls_21 ) OrbTools.p( 'linear series 12 =\n', ls_12 ) OrbTools.p( 'linear series 11a =\n', ls_11a ) OrbTools.p( 'linear series 11b =\n', ls_11b ) sig = ( 4, 1 ) pol_lst = ls_22.get_implicit_image() # determine signature x_lst = sage_PolynomialRing( sage_QQ, [ 'x' + str( i ) for i in range( sum( sig ) )] ).gens() for pol in pol_lst: if pol.degree() == 2: M = sage_invariant_theory.quadratic_form( pol, x_lst ).as_QuadraticForm().matrix() D, V = sage_matrix( sage_QQ, M ).eigenmatrix_right() # D has first all negative values on diagonal cur_sig = ( len( [ d for d in D.diagonal() if d < 0 ] ), len( [ d for d in D.diagonal() if d > 0 ] ) ) else: cur_sig = '[no signature]' OrbTools.p( '\t\t', pol, cur_sig ) # obtain surface in sphere coef_lst = [0, -1, -1] dct = get_surf( ls_22, sig, coef_lst ) # construct projection matrix P U, J = dct['UJ'] U.swap_rows( 0, 4 ) J.swap_columns( 0, 4 ) J.swap_rows( 0, 4 ) assert dct['M'] == approx_QQ( U.T * J * U ) approxU = approx_QQ( U ) P = sage_identity_matrix( 5 ).submatrix( 0, 0, 4, 5 ) P[0, 4] = -1; P = P * approxU OrbTools.p( ' approx_QQ( U ) =', list( approx_QQ( U ) ) ) OrbTools.p( ' approx_QQ( J ) =', list( approx_QQ( J ) ) ) OrbTools.p( ' P =', list( P ) ) # call get_proj f_xyz, pmz_AB_lst = get_proj( dct['imp_lst'], dct['pmz_lst'], P ) f_xyz_deg_lst = [f_xyz.degree( sage_var( v ) ) for v in ['x', 'y', 'z']] # compute reparametrization ring = PolyRing( 'x,y,v,w,c0,s0,c1,s1' ) # construct polynomial ring with new generators p_lst = ring.coerce( ls_22.pol_lst ) x, y, v, w, c0, s0, c1, s1 = ring.gens() X = 1 - s0; Y = c0; # see get_S1xS1_pmz() V = 1 - s1; W = c1; CB_dct = { x:X, y:Y, v:X * W + Y * V, w: X * V - Y * W } DB_dct = { x:X, y:Y, v:4 * X * W - Y * V, w: X * V + Y * W } EB_dct = { x:X, y:Y, v:40 * W * X ** 2 + 25 * W * Y ** 2 + 24 * V * X * Y, w:40 * V * X ** 2 + 16 * V * Y ** 2 - 15 * W * X * Y } AF_dct = { x:-10 * Y * V ** 2 - 25 * Y * W ** 2 + 9 * X * V * W, y:15 * X * V ** 2 + 24 * X * W ** 2 - 15 * Y * V * W, v:V, w:W } pmz_CB_lst = list( P * sage_vector( [ p.subs( CB_dct ) for p in p_lst] ) ) pmz_DB_lst = list( P * sage_vector( [ p.subs( DB_dct ) for p in p_lst] ) ) pmz_EB_lst = list( P * sage_vector( [ p.subs( EB_dct ) for p in p_lst] ) ) pmz_AF_lst = list( P * sage_vector( [ p.subs( AF_dct ) for p in p_lst] ) ) # output OrbTools.p( 'f_xyz =', f_xyz_deg_lst, '\n', f_xyz ) OrbTools.p( 'pmz_AB_lst =\n', pmz_AB_lst ) OrbTools.p( 'pmz_CB_lst =\n', pmz_CB_lst ) OrbTools.p( 'pmz_DB_lst =\n', pmz_DB_lst ) OrbTools.p( 'pmz_EB_lst =\n', pmz_EB_lst ) OrbTools.p( 'pmz_AF_lst =\n', pmz_AF_lst ) # mathematica pmz_lst = [ ( pmz_AB_lst, 'AB' ), ( pmz_CB_lst, 'CB' ), ( pmz_DB_lst, 'DB' ), ( pmz_EB_lst, 'EB' ), ( pmz_AF_lst, 'AF' )] OrbTools.p( 'Mathematica input for ParametricPlot3D:' ) for pmz, AB in pmz_lst: s = 'pmz' + AB + '=' + str( pmz ) s = s.replace( '[', '{' ).replace( ']', '}' ) print( s ) # PovInput for Blum cyclide # pin = PovInput() pin.path = './' + get_time_str() + '_blum_cyclide/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = ( 0, -7, 0 ) pin.cam_dct['lookat'] = ( 0, 0, 0 ) pin.cam_dct['rotate'] = ( 20, 180, 20 ) pin.shadow = True pin.light_lst = [( 0, 0, -5 ), ( 0, -5, 0 ), ( -5, 0, 0 ), ( 0, 0, 5 ), ( 0, 5, 0 ), ( 5, 0, 0 ), ( -5, -5, -5 ), ( 5, -5, 5 ), ( -5, -5, 5 ), ( 5, -5, -5 ) ] pin.axes_dct['show'] = False pin.axes_dct['len'] = 1.2 pin.height = 400 pin.width = 800 pin.quality = 11 pin.ani_delay = 10 pin.impl = None start0 = sage_QQ( 1 ) / 10 # step0=10 step1=15 v0_lst = [ start0 + ( sage_QQ( i ) / 180 ) * sage_pi for i in range( 0, 360, 10 )] v1_lst = [ ( sage_QQ( i ) / 180 ) * sage_pi for i in range( 0, 360, 15 )] v1_lst_F = [ start0 + ( sage_QQ( i ) / 360 ) * sage_pi for i in range( 0, 720, 1 )] v1_lst_WE = [1.8, 2.3, 2.7, 3.1, 3.5, 3.8, 4.134, 4.31, 4.532, 4.7, 4.9, 5.08, 5.25, 5.405, 5.553, 5.7, 5.84] v1_lst_WF = [1.69, 1.87, 2.07, 2.26, 2.5, 2.72, 2.96, 3.2, 3.42, 3.65, 3.81] v1_lst_WD = [ 5.44, 5.56, 5.68, 5.81, 5.95, 6.1, 6.27, 6.474] # [5.01, 5.12, 5.22, 5.32, v1_lst_SA = [6.5]; v1_lst_SE = [5.4]; v1_lst_SB = [5.95]; v1_lst_SF = [2.28]; v1_lst_SC = [4.83]; v1_lst_SD = [5.55]; pin.pmz_dct['A'] = ( pmz_AB_lst, 0 ) pin.pmz_dct['B'] = ( pmz_AB_lst, 1 ) pin.pmz_dct['C'] = ( pmz_CB_lst, 0 ) pin.pmz_dct['D'] = ( pmz_DB_lst, 0 ) pin.pmz_dct['E'] = ( pmz_EB_lst, 0 ) pin.pmz_dct['F'] = ( pmz_AF_lst, 1 ) pin.pmz_dct['WD'] = ( pmz_DB_lst, 0 ) pin.pmz_dct['WE'] = ( pmz_EB_lst, 0 ) pin.pmz_dct['WF'] = ( pmz_AF_lst, 1 ) pin.pmz_dct['SA'] = ( pmz_AB_lst, 0 ) pin.pmz_dct['SB'] = ( pmz_AB_lst, 1 ) pin.pmz_dct['SC'] = ( pmz_CB_lst, 0 ) pin.pmz_dct['SD'] = ( pmz_DB_lst, 0 ) pin.pmz_dct['SE'] = ( pmz_EB_lst, 0 ) pin.pmz_dct['SF'] = ( pmz_AF_lst, 1 ) pin.pmz_dct['FA'] = ( pmz_AB_lst, 0 ) pin.pmz_dct['FB'] = ( pmz_AB_lst, 1 ) pin.pmz_dct['FC'] = ( pmz_CB_lst, 0 ) pin.pmz_dct['FD'] = ( pmz_DB_lst, 0 ) pin.pmz_dct['FE'] = ( pmz_EB_lst, 0 ) pin.pmz_dct['FF'] = ( pmz_AF_lst, 1 ) pin.curve_dct['A'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['B'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['C'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['D'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['E'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['F'] = {'step0':v0_lst, 'step1':v1_lst, 'prec':10, 'width':0.05} pin.curve_dct['WD'] = {'step0':v0_lst, 'step1':v1_lst_WD, 'prec':10, 'width':0.05} pin.curve_dct['WE'] = {'step0':v0_lst, 'step1':v1_lst_WE, 'prec':10, 'width':0.05} pin.curve_dct['WF'] = {'step0':v0_lst, 'step1':v1_lst_WF, 'prec':10, 'width':0.05} pin.curve_dct['SA'] = {'step0':v0_lst, 'step1':v1_lst_SA, 'prec':10, 'width':0.05} pin.curve_dct['SB'] = {'step0':v0_lst, 'step1':v1_lst_SB, 'prec':10, 'width':0.05} pin.curve_dct['SC'] = {'step0':v0_lst, 'step1':v1_lst_SC, 'prec':10, 'width':0.05} pin.curve_dct['SD'] = {'step0':v0_lst, 'step1':v1_lst_SD, 'prec':10, 'width':0.06} pin.curve_dct['SE'] = {'step0':v0_lst, 'step1':v1_lst_SE, 'prec':10, 'width':0.05} pin.curve_dct['SF'] = {'step0':v0_lst, 'step1':v1_lst_SF, 'prec':10, 'width':0.05} pin.curve_dct['FA'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} pin.curve_dct['FB'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} pin.curve_dct['FC'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} pin.curve_dct['FD'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} pin.curve_dct['FE'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} pin.curve_dct['FF'] = {'step0':v0_lst, 'step1':v1_lst_F, 'prec':10, 'width':0.01} col_A = rgbt2pov( ( 28, 125, 154, 0 ) ) # blue col_B = rgbt2pov( ( 74, 33, 0, 0 ) ) # brown col_C = rgbt2pov( ( 75, 102, 0, 0 ) ) # green col_E = col_A col_F = col_B col_D = col_C colFF = rgbt2pov( ( 179, 200, 217, 0 ) ) # light blue pin.text_dct['A'] = [True, col_A, 'phong 0.2' ] pin.text_dct['B'] = [True, col_B, 'phong 0.2' ] pin.text_dct['C'] = [True, col_C, 'phong 0.2' ] pin.text_dct['E'] = [True, col_E, 'phong 0.2' ] pin.text_dct['F'] = [True, col_F, 'phong 0.2' ] pin.text_dct['D'] = [True, col_D, 'phong 0.2' ] pin.text_dct['WE'] = [True, col_E, 'phong 0.2' ] pin.text_dct['WF'] = [True, col_F, 'phong 0.2' ] pin.text_dct['WD'] = [True, col_D, 'phong 0.2' ] pin.text_dct['SA'] = [True, col_A, 'phong 0.2' ] pin.text_dct['SB'] = [True, col_B, 'phong 0.2' ] pin.text_dct['SC'] = [True, col_C, 'phong 0.2' ] pin.text_dct['SE'] = [True, col_E, 'phong 0.2' ] pin.text_dct['SF'] = [True, col_F, 'phong 0.2' ] pin.text_dct['SD'] = [True, col_D, 'phong 0.2' ] pin.text_dct['FA'] = [True, colFF, 'phong 0.2' ] pin.text_dct['FB'] = [True, colFF, 'phong 0.2' ] pin.text_dct['FC'] = [True, colFF, 'phong 0.2' ] pin.text_dct['FE'] = [True, colFF, 'phong 0.2' ] pin.text_dct['FF'] = [True, colFF, 'phong 0.2' ] pin.text_dct['FD'] = [True, colFF, 'phong 0.2' ] # raytrace image/animation F_lst = ['FA', 'FB', 'FC'] S_lst = ['SA', 'SB', 'SC', 'SD', 'SE', 'SF'] create_pov( pin, ['A', 'B', 'C'] ) create_pov( pin, ['A', 'B', 'C'] + F_lst ) create_pov( pin, ['WD', 'WE', 'WF'] ) create_pov( pin, ['WD', 'WE', 'WF'] + F_lst ) create_pov( pin, S_lst + F_lst ) # ABC - EFD create_pov( pin, ['A', 'B'] + F_lst ) create_pov( pin, ['E', 'F'] + F_lst )
def ring_cyclide(): ''' Creates povray image of 4 families of circles on a ring cyclide. ''' # We construct a trigonometric parametrization of the ring cyclide, # by rotating a circle of radius r along a circle of radius R. R = 2 r = 1 x, y, v, w, c0, s0, c1, s1 = sage_var('x,y,v,w,c0,s0,c1,s1') V = sage_vector([r * c0 + R, 0, r * s0]) M = sage_matrix([(c1, -s1, 0), (s1, c1, 0), (0, 0, 1)]) pmz_AB_lst = [1] + list(M * V) OrbTools.p('pmz_AB_lst =', pmz_AB_lst) for pmz in pmz_AB_lst: OrbTools.p('\t\t', sage_factor(pmz)) # convert pmz_AB_lst to rational parametrization pmz_lst C0 = (y**2 - x**2) / (y**2 + x**2) S0 = 2 * x * y / (y**2 + x**2) C1 = (w**2 - v**2) / (w**2 + v**2) S1 = 2 * v * w / (w**2 + v**2) den = (y**2 + x**2) * (w**2 + v**2) dct = {c0: C0, s0: S0, c1: C1, s1: S1} pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full() for elt in list(M * V)] OrbTools.p('pmz_lst =', pmz_lst) # find basepoints ls = LinearSeries(pmz_lst, PolyRing('x,y,v,w', True)) OrbTools.p(ls.get_bp_tree()) # construct linear series for families of conics a0, a1 = PolyRing('x,y,v,w').ext_num_field('t^2+1/3').ext_num_field( 't^2+1').root_gens() p1 = ['xv', (-a0, a1)] p2 = ['xv', (a0, -a1)] p3 = ['xv', (-a0, -a1)] p4 = ['xv', (a0, a1)] bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_1234.add(p1[0], p1[1], 1) bpt_1234.add(p2[0], p2[1], 1) bpt_1234.add(p3[0], p3[1], 1) bpt_1234.add(p4[0], p4[1], 1) bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_12.add(p1[0], p1[1], 1) bpt_12.add(p2[0], p2[1], 1) bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw']) bpt_34.add(p3[0], p3[1], 1) bpt_34.add(p4[0], p4[1], 1) ls_22 = LinearSeries.get([2, 2], bpt_1234) # |2(l1+l2)-e1-e2-e3-e4| ls_21 = LinearSeries.get([2, 1], bpt_1234) ls_12 = LinearSeries.get([1, 2], bpt_1234) ls_11a = LinearSeries.get([1, 1], bpt_12) ls_11b = LinearSeries.get([1, 1], bpt_34) OrbTools.p('linear series 22 =\n', ls_22) OrbTools.p('linear series 21 =\n', ls_21) OrbTools.p('linear series 12 =\n', ls_12) OrbTools.p('linear series 11a =\n', ls_11a) OrbTools.p('linear series 11b =\n', ls_11b) # compute reparametrization ring = PolyRing( 'x,y,v,w,c0,s0,c1,s1') # construct polynomial ring with new generators pmz_lst = ring.coerce(pmz_lst) x, y, v, w, c0, s0, c1, s1 = ring.gens() X = 1 - s0 Y = c0 # see get_S1xS1_pmz() V = 1 - s1 W = c1 q = sage_n(sage_sqrt(3)).exact_rational() # approximation of sqrt(3) CB_dct = {x: X, y: Y, v: W * X + q * V * Y, w: V * X - q * W * Y} DB_dct = {x: X, y: Y, v: W * X - q * V * Y, w: V * X + q * W * Y} pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst] pmz_DB_lst = [pmz.subs(DB_dct) for pmz in pmz_lst] # output OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst) OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst) OrbTools.p('pmz_DB_lst =\n', pmz_DB_lst) # mathematica for pmz, AB in [(pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB'), (pmz_DB_lst, 'DB')]: s = 'pmz' + AB + '=' + str(pmz) + ';' s = s.replace('[', '{').replace(']', '}') print(s) # PovInput ring cyclide # pin = PovInput() pin.path = './' + get_time_str() + '_ring_cyclide/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = (0, -7, 0) pin.cam_dct['lookat'] = (0, 0, 0) pin.cam_dct['rotate'] = (55, 0, 0) # 45 pin.shadow = True pin.light_lst = [(0, 0, -5), (0, -5, 0), (-5, 0, 0), (0, 0, 5), (0, 5, 0), (5, 0, 0), (-5, -5, -5), (5, -5, 5), (-5, -5, 5), (5, -5, -5)] pin.axes_dct['show'] = False pin.axes_dct['len'] = 1.2 pin.width = 800 pin.height = 400 pin.quality = 11 pin.ani_delay = 10 pin.impl = None pin.pmz_dct['A'] = (pmz_AB_lst, 0) pin.pmz_dct['B'] = (pmz_AB_lst, 1) pin.pmz_dct['C'] = (pmz_CB_lst, 0) pin.pmz_dct['D'] = (pmz_DB_lst, 0) pin.pmz_dct['FA'] = (pmz_AB_lst, 0) pin.pmz_dct['FB'] = (pmz_AB_lst, 1) pin.pmz_dct['FC'] = (pmz_CB_lst, 0) pin.pmz_dct['FD'] = (pmz_DB_lst, 0) pin.pmz_dct['WA'] = (pmz_AB_lst, 0) pin.pmz_dct['WB'] = (pmz_AB_lst, 1) pin.pmz_dct['WC'] = (pmz_CB_lst, 0) pin.pmz_dct['WD'] = (pmz_DB_lst, 0) v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] v1_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)] v1_lst_A = [ sage_pi / 2 + (sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 12) ] v1_lstFF = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 1)] v1_lst_WA = [ 0.1, 0.52, 0.94, 1.36, 1.78, 2.2, 2.61, 3.04, 3.45, 3.88, 4.3, 4.712, 5.13, 5.55, 5.965 ] v1_lst_WB = [ 0, 0.7, 1.31, 1.8, 2.18, 2.5, 2.77, 3.015, 3.26, 3.51, 3.78, 4.099, 4.49, 4.97, 5.579 ] v1_lst_WD = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)] v1_lst_WC = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)] pin.curve_dct['A'] = { 'step0': v0_lst, 'step1': v1_lst_A, 'prec': 10, 'width': 0.05 } pin.curve_dct['B'] = { 'step0': v0_lst, 'step1': v1_lst, 'prec': 10, 'width': 0.05 } pin.curve_dct['C'] = { 'step0': v0_lst, 'step1': v1_lst, 'prec': 10, 'width': 0.05 } pin.curve_dct['D'] = { 'step0': v0_lst, 'step1': v1_lst, 'prec': 10, 'width': 0.05 } pin.curve_dct['FA'] = { 'step0': v0_lst, 'step1': v1_lstFF, 'prec': 10, 'width': 0.02 } pin.curve_dct['FB'] = { 'step0': v0_lst, 'step1': v1_lstFF, 'prec': 10, 'width': 0.02 } pin.curve_dct['FC'] = { 'step0': v0_lst, 'step1': v1_lstFF, 'prec': 10, 'width': 0.02 } pin.curve_dct['FD'] = { 'step0': v0_lst, 'step1': v1_lstFF, 'prec': 10, 'width': 0.02 } pin.curve_dct['WA'] = { 'step0': v0_lst, 'step1': v1_lst_WA, 'prec': 10, 'width': 0.05 } pin.curve_dct['WB'] = { 'step0': v0_lst, 'step1': v1_lst_WB, 'prec': 10, 'width': 0.05 } pin.curve_dct['WC'] = { 'step0': v0_lst, 'step1': v1_lst_WC, 'prec': 10, 'width': 0.05 } pin.curve_dct['WD'] = { 'step0': v0_lst, 'step1': v1_lst_WD, 'prec': 10, 'width': 0.05 } # A = | rotated circle # B = - horizontal circle # C = / villarceau circle # D = \ villarceau circle col_A = rgbt2pov((28, 125, 154, 0)) # blue col_B = rgbt2pov((74, 33, 0, 0)) # brown col_C = rgbt2pov((75, 102, 0, 0)) # green col_D = rgbt2pov((187, 46, 0, 0)) # red/orange colFF = rgbt2pov((179, 200, 217, 0)) # light blue pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5'] pin.text_dct['D'] = [True, col_D, 'phong 0.2 phong_size 5'] pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FD'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['WA'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['WB'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['WC'] = [True, col_C, 'phong 0.2 phong_size 5'] pin.text_dct['WD'] = [True, col_D, 'phong 0.2 phong_size 5'] # raytrace image/animation create_pov(pin, ['A', 'C', 'D']) create_pov(pin, ['A', 'C', 'D'] + ['FA', 'FC', 'FD']) create_pov(pin, ['WA', 'WB', 'WC', 'WD']) create_pov(pin, ['WA', 'WB', 'WC', 'WD'] + ['FA', 'FC', 'FD']) create_pov(pin, ['WA', 'WB', 'WD']) create_pov(pin, ['WA', 'WB', 'WD'] + ['FA', 'FC', 'FD'])
def get_project( pol_lst, pmat ): ''' Parameters ---------- pol_lst : list<OrbRing.R> A list of homogeneous polynomials in QQ[x0,...,x8]. pmat : sage_matrix A matrix defined over the rationals QQ. Returns ------- tuple A 2-tuple of polynomials: * a homogeneous polynomial F in QQ[x0,x1,x2,x3]. * F(1,x,y,z) in QQ[x,y,z] (affine polynomial) ''' Ry = sage_PolynomialRing( sage_GF( 2 ), sage_var( 'y0,y1,y2,y3,y4,y5,y6,y7,y8' ), order = 'degrevlex' ) v = OrbRing.coerce( '[v0,v1,v2,v3,v4,v5,v6,v7,v8]' ) x = OrbRing.coerce( '[x0,x1,x2,x3,x4,x5,x6,x7,x8]' ) vx_dct = {v[i]:x[i] for i in range( 9 )} OrbTools.p( "\n" + str( pmat ) ) tries = 0 projected = False while not projected: # obtain the linear equations of the projection map pmat = sage_matrix( OrbRing.R, list( pmat ) ) leq_lst = list( pmat * sage_vector( x ) ) # compute the image of this projection map proj_lst = [ v[i] - leq_lst[i] for i in range( len( leq_lst ) ) ] p_lst = sage_ideal( pol_lst + proj_lst ).elimination_ideal( x ).gens() # obtain a polynomial in x0,...,x8 p_lst = [p.subs( vx_dct ) for p in p_lst] fx = p_lst[0] tries += 1 if len( fx.variables() ) < 4 or len( p_lst ) != 1: pmat = get_pmat( True ) if tries % 100 == 0: OrbTools.p( 'tries =', tries, p_lst ) if tries == 1000: return -1 else: projected = True w0, w1, w2, w3 = fx.variables() fx = fx.subs( {w0:x[0], w1:x[1], w2:x[2], w3:x[3]} ) x0, x1, x2, x3 = OrbRing.coerce( 'x0,x1,x2,x3' ) x, y, z = sage_var( 'x,y,z' ) fxyz = fx.subs( {x0:1, x1:x, x2:y, x3:z} ) OrbTools.p( fx ) OrbTools.p( fxyz ) return fx, fxyz
def get_imp(A, B, prj, sng, snp): ''' Computes implicit equation of a stereographic projection S of the pointwise Hamiltonian product of circles in the sphere S^3 defined by transformations of the standard circle [1,cos(a),sin(a),0,0] by A and B respectively. Parameters ---------- A : sage_Matrix<sage_QQ> Represents a linear transformation S^3--->S^3 B : sage_Matrix<sage_QQ> Represents a linear transformation S^3--->S^3 prj : int Choice for stereographic projection S^3--->P^3: 0: (x0:x1:x2:x3:x4) |--> (x0-x4:x1:x2:x3) 1: (x0:x1:x2:x3:x4) |--> (x0-x1:x4:x2:x3) 2: (x0:x1:x2:x3:x4) |--> (x0-x2:x1:x4:x3) 3: (x0:x1:x2:x3:x4) |--> (x0-x3:x1:x2:x4) sng : boolean If true computes singular locus of S. Needs Magma path set in os.environ['PATH']. Otherwise the empty-list is returned. snp : boolean If true and if sng is True, then the singular locus is computed with a probablistic method, which is faster but the correctness of the output is not guaranteed. Returns ------- dict { 'Agreat' : boolean If True, then circle A is great. 'Bgreat' : boolean If True, then circle B is great. 'eqn_x' : sage_PolynomialRing Equation of S in x0,...,x3 'eqn_str': Formatted equation in x0,...,x3 of the form f(x1:x2:x3)+x0*g(x0:x1:x2:x3). 'eqn_xyz': Equation of S in x,y,z 'sng_lst': Empty-list if Magma is not installed or list of singularities of S otherwise. } ''' dct = {} # output # create polynomial ring # R = sage_PolynomialRing(sage_QQ, 'x0,x1,x2,x3,a0,a1,a2,a3,a4,b0,b1,b2,b3,b4') x0, x1, x2, x3, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4 = R.gens() # construct ideal for A # sv = [0, 0, 0, 1, 0] tv = [0, 0, 0, 0, 1] u0, u1, u2, u3, u4 = list(A * sage_vector(sv)) v0, v1, v2, v3, v4 = list(A * sage_vector(tv)) eqA = [-a0**2 + a1**2 + a2**2 + a3**2 + a4**2] eqA += [u0 * a0 + u1 * a1 + u2 * a2 + u3 * a3 + u4 * a4] eqA += [v0 * a0 + v1 * a1 + v2 * a2 + v3 * a3 + v4 * a4] dct['Agreat'] = u0 == v0 == 0 # construct ideal for B # u0, u1, u2, u3, u4 = list(B * sage_vector(sv)) v0, v1, v2, v3, v4 = list(B * sage_vector(tv)) eqB = [-b0**2 + b1**2 + b2**2 + b3**2 + b4**2] eqB += [u0 * b0 + u1 * b1 + u2 * b2 + u3 * b3 + u4 * b4] eqB += [v0 * b0 + v1 * b1 + v2 * b2 + v3 * b3 + v4 * b4] dct['Bgreat'] = u0 == v0 == 0 # stereographic projection # if prj == 0: j, i_lst = 4, [1, 2, 3] if prj == 1: j, i_lst = 1, [4, 2, 3] if prj == 2: j, i_lst = 2, [1, 4, 3] if prj == 3: j, i_lst = 3, [1, 2, 4] # construct equation of for projection of A*B # c = c0, c1, c2, c3, c4 = get_hp_P4([a0, a1, a2, a3, a4], [b0, b1, b2, b3, b4]) x = [x0, x1, x2, x3] i1, i2, i3 = i_lst id = [x[0] - (c[0] - c[j]), x[1] - c[i1], x2 - c[i2], x3 - c[i3]] + eqA + eqB dct['eqn_x'] = eqn_x = R.ideal(id).elimination_ideal( [a0, a1, a2, a3, a4, b0, b1, b2, b3, b4]).gens()[0] # get equation in string form # f = eqn_x.subs({x0: 0}) dct['eqn_str'] = str(sage_factor(f)) + '+' + str(sage_factor(eqn_x - f)) xs, ys, zs = sage_var('x,y,z') dct['eqn_xyz'] = sage_SR(eqn_x.subs({x0: 1, x1: xs, x2: ys, x3: zs})) # compute singular locus # dct['sng_lst'] = [] if sng: dct['sng_lst'] = get_sing_lst(OrbRing.coerce(eqn_x), snp) return dct
def spindle_cyclide(): ''' Constructs a povray image of a spindle cyclide. The spindle cyclide is an inversion of a circular cylinder. ''' # We construct a trigonometric parametrization # of the cyclide by rotating a circle. # r = 1 R = 1 # radii of circles x, y, v, w = sage_var('x,y,v,w') c0, s0, c1, s1 = sage_var('c0,s0,c1,s1') V = sage_vector([r * c0 + R, 0, r * s0]) M = sage_matrix([(c1, -s1, 0), (s1, c1, 0), (0, 0, 1)]) pmz_AB_lst = [1] + list(M * V) OrbTools.p('pmz_AB_lst =', pmz_AB_lst) for pmz in pmz_AB_lst: OrbTools.p('\t\t', sage_factor(pmz)) # PovInput spindle cyclide # pin = PovInput() pin.path = './' + get_time_str() + '_spindle_cyclide/' pin.fname = 'orb' pin.scale = 1 pin.cam_dct['location'] = (0, -5, 0) pin.cam_dct['lookat'] = (0, 0, 0) pin.cam_dct['rotate'] = (45, 0, 0) pin.shadow = True pin.light_lst = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0), (0, -1, 0), (0, 0, -1), (10, 0, 0), (0, 10, 0), (0, 0, 10), (-10, 0, 0), (0, -10, 0), (0, 0, -10)] pin.axes_dct['show'] = False pin.axes_dct['len'] = 1.2 pin.height = 400 pin.width = 800 pin.quality = 11 pin.ani_delay = 10 pin.impl = None pin.pmz_dct['A'] = (pmz_AB_lst, 0) pin.pmz_dct['B'] = (pmz_AB_lst, 1) pin.pmz_dct['FA'] = (pmz_AB_lst, 0) pin.pmz_dct['FB'] = (pmz_AB_lst, 1) v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)] v1_lst_A = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 270, 15)] v1_lst_B = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 15)] v1_lstFA = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 270 - 15, 1)] v1_lstFB = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 1)] pin.curve_dct['A'] = { 'step0': v0_lst, 'step1': v1_lst_A, 'prec': 10, 'width': 0.03 } pin.curve_dct['B'] = { 'step0': v0_lst, 'step1': v1_lst_B, 'prec': 10, 'width': 0.03 } pin.curve_dct['FA'] = { 'step0': v0_lst, 'step1': v1_lstFA, 'prec': 10, 'width': 0.02 } pin.curve_dct['FB'] = { 'step0': v0_lst, 'step1': v1_lstFB, 'prec': 10, 'width': 0.02 } col_A = (0.6, 0.4, 0.1, 0.0) col_B = (0.1, 0.15, 0.0, 0.0) colFF = (0.1, 0.1, 0.1, 0.0) pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5'] pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5'] pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5'] pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5'] # raytrace image/animation create_pov(pin, ['A', 'B']) create_pov(pin, ['A', 'B', 'FA', 'FB'])
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