Beispiel #1
0
def get_pmz_verify( o ):
    '''
    Parameters
    ----------
        o : OrbOutput
    
    Returns
    -------
    Boolean
        * Return "None" if the test could not be performed because
          either parametrization or implicit equation was not available.            
        * Return "True" if implicit equation of projected surface
          agrees with parametrization composed with projection.          
        * Return "False" if both parametrization and implicit equation were 
          available but do not agree.               
    '''

    if not o.input.do['pmz'] or not o.input.do['imp']:
        return None

    if o.prj_pol == -1 or o.gen == -2:
        return False

    OrbTools.p( 'Testing parametrization...' )
    c0, s0, c1, s1 = OrbRing.coerce( 'c0,s0,c1,s1' )
    x0, x1, x2, x3 = OrbRing.coerce( 'x0,x1,x2,x3' )
    f = o.prj_pol
    p = o.prj_pmz_lst
    fp = o.prj_pol.subs( {x0:p[0], x1:p[1], x2:p[2], x3:p[3]} )
    test = fp.reduce( [c0 * c0 + s0 * s0 - 1, c1 * c1 + s1 * s1 - 1] )
    OrbTools.p( test )
    if test != 0:
        return False

    return True
Beispiel #2
0
def get_genus( pol, plane = 'x1+2*x2+17*x3+11*x0' ):
    '''
    The method requires that the maple-command 
    is in "os.environ['PATH']". 
    See [https://www.maplesoft.com].
    
    Parameters
    ----------
    pol : OrbRing.R
        A polynomial in QQ[x0,x1,x2,x3].
    
    plane : string 
        A String of a linear polynomial in QQ[x0,x1,x2,x3].
        
    Returns
    -------
    int
        An integer denoting the geometric genus of
        the curve given by the intersection of the 
        surface defined by "pol", with the plane defined 
        by "plane". If this geometric genus is not defined, 
        then -2 is returned. 
        If Maple is not installed then -3 is returned.
    '''
    OrbTools.p( pol )

    # obtain an equation for the curve defined
    # intersecting a plane with the zero-set of pol.
    plane = OrbRing.coerce( plane )
    K = sage_ideal( pol, plane ).groebner_basis()
    P = K[0]
    if P.total_degree() <= 1:
        P = K[1]
    P = P.subs( {OrbRing.coerce( 'x3' ):1} )

    # compute geometric genus with Maple.
    try:
        sage_maple.eval( 'with(algcurves);' )
    except:
        return -3

    sage_maple.eval( 'P := ' + str( P ) + ';' )
    gen = sage_maple.eval( 'genus(P,x1,x2);' )

    OrbTools.p( gen )

    try:
        return int( gen )
    except ValueError:
        return -2
Beispiel #3
0
def get_omat(o_str):
    '''
    Parameters
    ----------
    o_str : string
        A string with format:
            'O****'
        where the *-symbol is a place holder for
        one of the following characters: r,s,m,p,a.  
                    
    Returns
    -------
    sage_matrix
        A 9x9 matrix over "OrbRing.num_field" of the shape     
             
            1  0  0  0  0  0  0  0  0 
            0  *  *  0  0  0  0  0  0 
            0  *  *  0  0  0  0  0  0  
            0  0  0  *  *  0  0  0  0  
            0  0  0  *  *  0  0  0  0  
            0  0  0  0  0  *  *  0  0  
            0  0  0  0  0  *  *  0  0  
            0  0  0  0  0  0  0  *  *  
            0  0  0  0  0  0  0  *  *
            
        where each 2x2 matrix on the diagonal is of either 
        one of the following shapes:
                  
            'r': c0 -s0    's': -c0  s0      
                 s0  c0         -s0 -c0

            'p': 1  0    'm': -1  0    'a': 1  0
                 0  1          0 -1         0 -1
    
    '''
    # parse input
    if o_str[0] != 'O' or len(o_str) != 5:
        raise ValueError('Incorrect input string: ', o_str)

    c0, s0 = OrbRing.coerce('c0,s0')

    br = [[c0, -s0], [s0, c0]]
    bs = [[-c0, s0], [-s0, -c0]]
    bp = [[1, 0], [0, 1]]
    bm = [[-1, 0], [0, -1]]
    ba = [[1, 0], [0, -1]]
    b_dct = {'r': br, 's': bs, 'p': bp, 'm': bm, 'a': ba}

    bmat_lst = []
    for ch in o_str[1:]:
        bmat_lst += [b_dct.get(ch, 'error')]

    omat = sage_identity_matrix(OrbRing.R, 9)
    idx = 1
    for bmat in bmat_lst:
        omat.set_block(idx, idx, sage_matrix(OrbRing.R, bmat))
        idx = idx + 2

    return omat
Beispiel #4
0
    def test__get_project( self ):

        pol_lst = OrbRing.coerce( '[-x0^2+x1^2+x2^2+x3^2+x4^2+x5^2+x6^2+x7^2+x8^2, x8, x7, x6, x5, x1*x2-x0*x4]' )
        pmat = get_pmat( False )
        print( pmat )

        out = get_project( pol_lst, pmat )
        print( out )
        assert str( out ) == '(x0^4 - x0^2*x1^2 - x0^2*x2^2 - x1^2*x2^2 - x0^2*x3^2, -x^2*y^2 - x^2 - y^2 - z^2 + 1)'
Beispiel #5
0
def get_pmz_value( pmz_lst, v0, v1, prec = 50 ):
    '''
    Parameters
    ----------
    pmz_lst : list<sage_POLY> 
        A list of 4 polynomials in QQ[c0,s0,c1,s1].
    
    v0 : sage_REALNUMBER      
        A real number in [0,2*pi)
    
    v1 : sage_REALNUMBER       
        A real number in [0,2*pi)
    
    prec : int    
        Number of digits.

    scale : int
        A positive integer.
    
    Returns
    -------
    list<float>
        Returns a point in R^3 represented by a list of 3 float 
        values with precision "prec":  
            F(a,b)=[ x, y, z  ].
        Here F(a,b) is represented by "pmz_lst" and
        has the following domain and range:  
              F: [0,2*pi)X[0,2*pi) ---> R^3.
        The parametrization is a map in terms of cosine and sine.   
        
        If F is not defined at the point it first looks at (v0-dv,v1-dv) 
        where dv is very small. If that does not work, then we return None.
               
    '''
    c0, s0, c1, s1, t0, t1 = OrbRing.coerce( 'c0,s0,c1,s1,t0,t1' )

    dct = {c0:sage_cos( v0 ), s0:sage_sin( v0 ), c1:sage_cos( v1 ), s1:sage_sin( v1 ), t0:v0, t1:v1}


    if type( pmz_lst[0] ) == int:
        W = sage_QQ( pmz_lst[0] )
    else:
        W = pmz_lst[0].subs( dct )

    X = pmz_lst[1].subs( dct )
    Y = pmz_lst[2].subs( dct )
    Z = pmz_lst[3].subs( dct )

    if W == 0:
        return None

    XW = round( X / W, prec )
    YW = round( Y / W, prec )
    ZW = round( Z / W, prec )

    return [ XW, YW, ZW ]
    def test__get_tmat(self):

        #
        # Setup inverse stereographic projection:
        # S: P^7 ---> S^7
        #
        v = OrbRing.coerce('[v0,v1,v2,v3,v4,v5,v6,v7,v8]')
        d = v[1]**2 + v[2]**2 + v[3]**2
        v0_2 = v[0]**2
        vec_lst = []
        vec_lst += [v0_2 + d]
        vec_lst += [2 * v[0] * v[1]]
        vec_lst += [2 * v[0] * v[2]]
        vec_lst += [2 * v[0] * v[3]]
        vec_lst += [2 * v[0] * v[4]]
        vec_lst += [2 * v[0] * v[5]]
        vec_lst += [2 * v[0] * v[6]]
        vec_lst += [2 * v[0] * v[7]]
        vec_lst += [-v0_2 + d]
        x = sage_vector(OrbRing.R, vec_lst)
        print(x)

        #
        # Setup Euclidean translation in S^7
        #    T:S^7--->S^7
        #
        tmat = get_tmat(None)
        print(tmat)

        #
        # Setup stereographic projection
        #     P:S^7--->P^7
        #
        pmat = []
        pmat += [[1, 0, 0, 0] + [0, 0, 0, 0, -1]]
        pmat += [[0, 1, 0, 0] + [0, 0, 0, 0, 0]]
        pmat += [[0, 0, 1, 0] + [0, 0, 0, 0, 0]]
        pmat += [[0, 0, 0, 1] + [0, 0, 0, 0, 0]]
        pmat += [[0, 0, 0, 0] + [1, 0, 0, 0, 0]]
        pmat += [[0, 0, 0, 0] + [0, 1, 0, 0, 0]]
        pmat += [[0, 0, 0, 0] + [0, 0, 1, 0, 0]]
        pmat += [[0, 0, 0, 0] + [0, 0, 0, 1, 0]]
        pmat = sage_matrix(pmat)
        print(pmat)

        # Check whether composition is an Euclidean
        # translation in P^7:
        #    PoToS
        #
        tv = pmat * tmat * x
        tv = tv / (2 * v[0])
        print(tv)

        assert str(
            tv
        ) == '(v0, v0*t1 + v1, v0*t2 + v2, v0*t3 + v3, v0*t4 + v4, v0*t5 + v5, v0*t6 + v6, v0*t7 + v7)'
    def test__approx_QQ_coef__2(self):

        ring = PolyRing('x,y,v,w', True)
        ring.ext_num_field('t^2 - 3')
        ring.ext_num_field('t^2 + 1')
        ring.ext_num_field('t^2 + 2/7*a0*a1 + 3/7')
        ring.ext_num_field('t^2 - 2/7*a0*a1 + 3/7')
        a0, a1, a2, a3 = ring.root_gens()

        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

        ci_idx = 5  # index for complex embedding

        C1 = -(b + c - d - e)
        C2 = -(b + c + d + e)

        for lbl, elt in [('a0', a0), ('C1', C1), ('C2', C2)]:
            print(lbl + ' = ' + str(elt.abs()))
            for ci in elt.complex_embeddings():
                print('\t\t' + str(ci))
            s = str(elt.complex_embeddings()[ci_idx])
            print(lbl + '.complex_embedding()[' + str(ci_idx) + '] = ' + s)

        # C1
        print('--- C1 ---')
        out = OrbRing.approx_QQ_coef(C1, ci_idx)
        print(out)
        print(sage_n(out))
        chk = -sage_QQ(3687885631267691) / 2251799813685248
        assert out == chk

        # C2
        print('--- C2 ---')
        out = OrbRing.approx_QQ_coef(C2, ci_idx)
        print(out)
        print(sage_n(out))
        chk = sage_QQ(2749869658604311) / 4503599627370496
        assert out == chk
Beispiel #8
0
    def test__get_pmz_verify__perseus( self ):

        o = OrbOutput( OrbInput() )

        o.input.do['pmz'] = True
        o.input.do['imp'] = True

        o.prj_pmz_lst = '[-2*s1 + 3, 4/5*c0*c1 - 3/5*s0*c1 + 7/5*c0*s1 + 6/5*s0*s1 - 12/5*c0 - 11/5*s0 - 2*s1 + 3, 3/5*c0*c1 + 4/5*s0*c1 - 6/5*c0*s1 + 7/5*s0*s1 + 11/5*c0 - 12/5*s0, -2*s1 + 2]'
        o.prj_pmz_lst = OrbRing.coerce( o.prj_pmz_lst )

        o.prj_pol = '25*x0^4 + 100*x0^3*x1 + 50*x0^2*x1^2 - 100*x0*x1^3 + 25*x1^4 - 50*x0^2*x2^2 - 100*x0*x1*x2^2 + 50*x1^2*x2^2 + 25*x2^4 - 24*x0^3*x3 - 40*x0^2*x1*x3 + 20*x0*x1^2*x3 + 20*x0*x2^2*x3 - 41*x0^2*x3^2 - 100*x0*x1*x3^2 + 50*x1^2*x3^2 + 50*x2^2*x3^2 + 20*x0*x3^3 + 25*x3^4'
        o.prj_pol = OrbRing.coerce( o.prj_pol )

        o.gen = 1

        print( o )
        tst = get_pmz_verify( o )
        print( tst )
        assert tst == True
Beispiel #9
0
    def test__get_orb_bp_tree( self ):
        pmz_lst = OrbRing.coerce( '[2,c0,s0,c1,s1,c0,s0,c1,s1]' )
        bp_tree = get_orb_bp_tree( pmz_lst )
        print( bp_tree )

        out = str( bp_tree )

        assert 'chart=xv, depth=0, mult=1, sol=(a0, (a0))' in out
        assert 'chart=xv, depth=0, mult=1, sol=(a0, (-a0))' in out
        assert 'chart=xv, depth=0, mult=1, sol=(-a0, (-a0))' in out
        assert 'chart=xv, depth=0, mult=1, sol=(-a0, (a0))' in out
Beispiel #10
0
def usecase_orb_product_implicit_circle(num=10):
    '''
    Outputs "num" random surfaces in the projective n-sphere S^n, 
    that are obtained by rotating or translating an implicit circle.
    The circle is obtained as a random hyperplane section.
    
    The hyperplane section is obtained by applying 
    a random matrix in PGL(8+1) to the hyperplane 
    section { x | x3=..=x8=0=-x0^2+x1^2+...+x8^2=0 }.  
    Since the random matrix is not orthogonal
    we cannot use the matrix to compute parametric 
    presentations for these examples.  
    
    Notice that we can recover the OrbInput object 
    from the short string output 
    (see "usecase_orb_product_investigate_example()")
    
    Parameters
    ----------
    num : int
        Number of times a random surface should be computed.   
    '''

    for idx in range(num):
        try:

            # compute random input
            ch_str = ''.join([
                OrbRing.random_elt(['r', 's', 'p', 'm', 'a']) for i in range(4)
            ])
            pmat = list(sage_MatrixSpace(sage_ZZ, 9, 9).random_element())
            p_tup = ('P1', 'I', 'I')
            o_tup = ('I', 'O' + ch_str, 'I')
            v_tup = ('M' + str(pmat), 'I', 'I')
            input = OrbInput().set(p_tup, o_tup, v_tup)

            # compute only few attributes
            for key in input.do.keys():
                input.do[key] = False
            input.do['imp'] = True
            input.do['dde'] = True

            o = orb_product(input)

            OrbTools.p('(deg, emb, dim ) =',
                       (o.deg, o.emb, o.dim), ' short string =',
                       o.get_short_str())  # output  orbital product

        except BaseException as e:

            # continue with loop regardless of exceptions
            OrbTools.p('Exception occurred: ', e)
            OrbTools.p(input)
            OrbTools.p(o)
    def random(self, bnd=10):
        '''
        Sets attributes to random values. 
                
        Parameters
        ----------
        coef_bnd : int    
            Positive integer.
                             
        Returns
        -------
        self
            Sets self.rota, self.trna, self.sa and
            self.rotb, self.trnb, self.sb with random
            values.
            
        '''
        # OrbRing.random_int( coef_size )

        q4 = sage_QQ(1) / 4

        s_lst = [i * q4 for i in range(4 * bnd)]
        s_lst += [-s for s in s_lst]

        # circle A
        self.rota = [OrbRing.random_elt(range(360)) for i in range(6)]
        self.trna = [OrbRing.random_elt(range(360)) for i in range(3)]
        self.sa = OrbRing.random_elt(s_lst)

        # circle B
        self.rotb = [OrbRing.random_elt(range(360)) for i in range(6)]
        self.trnb = [OrbRing.random_elt(range(360)) for i in range(3)]
        self.sb = OrbRing.random_elt(s_lst)

        return self
    def test__approx_QQ_pol_lst(self):
        ring = PolyRing('x,y,z', True).ext_num_field('t^2 - 3')
        x, y, z = ring.gens()
        a0 = ring.root_gens()[0]
        q2 = sage_QQ(1) / 2
        pol_lst = [x * y * a0 + z**2 + q2 * y**2 - q2 - a0 * x, a0, -a0 * x]
        out_lst = OrbRing.approx_QQ_pol_lst(pol_lst, 1)

        c = sage_QQ(3900231685776981) / 2251799813685248

        print(out_lst)
        assert out_lst[0] == x * y * c + z**2 + q2 * y**2 - q2 - c * x
        assert out_lst[1] == c
        assert out_lst[2] == -c * x
    def test__approx_QQ_coef__1(self):

        ring = PolyRing('x,y,z', True).ext_num_field('t^2 - 3')
        a0 = ring.root_gens()[0]
        ci_idx = 1
        for lbl, elt in [('a0', a0), ('-a0', -a0)]:
            print(lbl + ' = ' + str(elt.abs()))
            for ci in elt.complex_embeddings():
                print('\t\t' + str(ci))
            s = str(elt.complex_embeddings()[ci_idx])
            print(lbl + '.complex_embedding()[' + str(ci_idx) + '] = ' + s)

        print('--- a0 ---')
        out = OrbRing.approx_QQ_coef(a0, ci_idx)
        chk = sage_QQ(3900231685776981) / 2251799813685248
        print(out)
        print(sage_n(out))
        assert out == chk

        print('--- (-a0) ---')
        out = OrbRing.approx_QQ_coef(-a0, ci_idx)
        print(out)
        print(sage_n(out))
        assert out == -chk
Beispiel #14
0
def get_pmz( pmat, omat, vmat ):
    '''
    Parameters
    ----------
    pmat : sage_matrix
        A 4x9 invertible matrix with entries in QQ. 
        A matrix represents a projection from 
        a 7-sphere in projective 8-space to projective 3-space.
        
    omat : sage_matrix 
        A 9x9 invertible matrix with entries in QQ[c1,s1]. 
        This matrix represents a projective curve 
        in the automorphism group of the projective 7-sphere.
        Thus "omat" represents a 1-parameter subgroup in Aut(S^7).
                    
    vmat : sage_matrix 
        A 9x9 invertible matrix with entries in QQ. 
        This matrix represents an element in Aut(S^7),
        which transforms a standard circle (see below).
        
    Returns
    -------
    list
        Two lists of elements in QQ[c0,s0,c1,s1].
        The 1st list has length 9 and the 2nd list has length 4.
        The 1st list represent a parametrization 
              S^1xS^1--->S^7
        of a surface in S^7 and the 2nd list the parametrization 
              S^1xS^1--->P^3
        of the surface projected into
        P^3 (projective 3-space) using "pmat". 
        Here (c0,s0) and (c1,s1) are points on S^1.
                    
    Notes
    -----
    The surface in S^7 is obtained by applying a 1-parameter subgroup to a 
    circle C. Here C is the "vmat"-transform of the standard circle B in S^7 
    where
    B = { x | -x0^2+x1^2+x2^2==0 } and S^7 = { x | -x0^2+x1^2+...+x8^2==0 }.             
    '''
    c1, s1 = OrbRing.coerce( 'c1,s1' )
    pmz_lst = list( omat * vmat * sage_vector( [1, c1, s1, 0, 0, 0, 0, 0, 0] ) )
    prj_pmz_lst = list( pmat * omat * vmat * sage_vector( [1, c1, s1, 0, 0, 0, 0, 0, 0] ) )

    return pmz_lst, prj_pmz_lst
Beispiel #15
0
def get_imp( omat, vmat ):
    '''
    Parameters
    ----------
    omat : sage_matrix 
        A 9x9 invertible matrix with entries in QQ[c0,s0]. 
        This matrix represents a projective curve 
        in the automorphism group of the projective 7-sphere.
        Thus "omat" represents a 1-parameter subgroup in Aut(S^7).
                    
    vmat : sage_matrix  
        A 9x9 invertible matrix with entries in QQ. 
        This matrix represents an element in Aut(S^7),
        which transforms a standard circle.    

    Returns
    -------
    list<OrbRing.R>
        A list of elements in QQ[x0,...,x8].
        This list represent the generators of the ideal corresponding to 
        the variety, which is obtained by applying a 1-parameter subgroup to
        a circle C. Here C is the "vmat"-transform of 
        the standard circle B in S^7 where        
        B = { x | -x0^2+x1^2+x2^2==0 } and S^7 = { x | -x0^2+x1^2+...+x8^2==0 }.   
    '''

    # declare list of coordinate variables
    v_lst = OrbRing.coerce( '[v0,v1,v2,v3,v4,v5,v6,v7,v8]' )
    x_lst = OrbRing.coerce( '[x0,x1,x2,x3,x4,x5,x6,x7,x8]' )
    c_lst = OrbRing.coerce( '[c0,s0]' )

    # construct generators of ideal of orbital product
    g_lst = []

    # v[i] coordinates of points on a circle C in S^7
    vmatI = vmat.inverse()
    g_lst += list( vmatI * sage_vector( v_lst ) )[3:]
    g_lst += OrbRing.coerce( '[-v0^2+v1^2+v2^2+v3^2+v4^2+v5^2+v6^2+v7^2+v8^2]' )

    # consider all point that are an orbit of C
    # the 1-parameter subgroup of Aut(S^7)
    # represented by the matrix omat
    e_lst = list( omat * sage_vector( v_lst ) )
    g_lst += [ x_lst[i] - e_lst[i] for i in range( 0, 8 + 1 ) ]
    g_lst += OrbRing.coerce( '[-x0^2+x1^2+x2^2+x3^2+x4^2+x5^2+x6^2+x7^2+x8^2]' )
    g_lst += OrbRing.coerce( '[s0^2+c0^2-1]' )

    # compute the resulting variety by elimination
    g_ideal = OrbRing.R.ideal( g_lst )
    imp_lst = list( g_ideal.elimination_ideal( v_lst + c_lst ).gens() )

    return imp_lst
Beispiel #16
0
    def test__get_sing_lst( self ):
        pol = OrbRing.coerce( '(x1^2+x2^2+x3^2+3*x0^2)^2-16*x0^2*(x1^2+x2^2)' )
        print( pol )

        os.environ['PATH'] += os.pathsep + '/home/niels/Desktop/n/app/magma/link'
        try:
            sage_magma.eval( 1 + 1 )
            print( 'Magma is installed.' )
        except:
            print( 'Magma is NOT installed.' )
            sng_lst = get_sing_lst( pol )
            print( sng_lst )
            assert sng_lst == []
            return

        sng_lst = get_sing_lst( pol )
        print( sng_lst )
        assert str( sng_lst ) == "[('[x0^2 + 1/3*x3^2,x1,x2]', 2), ('[x0,x1^2 + x2^2 + x3^2]', 2*t + 1)]"
    def __str__(self):

        if OrbOutput.short_str:
            return self.get_short_str()

        s = '\n'
        s += 30 * '-' + '\n'

        s += str(self.input) + '\n'

        s += 'pmz_lst       = ' + str(self.pmz_lst) + '\n'
        s += 'prj_pmz_lst   = ' + str(self.prj_pmz_lst) + '\n'
        s += 'imp_lst       = ' + str(self.imp_lst) + '\n'
        s += 'emb           = ' + str(self.emb) + '\n'
        s += 'dim           = ' + str(self.dim) + '\n'
        s += 'deg           = ' + str(self.deg) + '\n'
        s += 'gen           = ' + str(self.gen) + '\n'
        s += 'prj_pol       = ' + str(self.prj_pol) + '\n'
        if self.prj_pol != None:
            s += 'prj_pol{x0:0} = ' + str(
                sage_factor(self.prj_pol.subs({OrbRing.coerce('x0'): 0
                                               }))) + '\n'
        s += 'xyz_pol       = ' + str(self.xyz_pol) + '\n'
        s += 'pmz_test      = ' + str(self.pmz_test) + '\n'

        if self.fct_lst != None:
            s += 'fct_lst       = ' + str(len(self.fct_lst)) + ' factors\n'
            if len(self.fct_lst) > 1:
                for fct in self.fct_lst:
                    s += '              ~ ' + str(fct) + '\n'

        if self.sng_lst != None:
            s += 'sng_lst       = ' + str(len(self.sng_lst)) + ' components\n'
            for sng in self.sng_lst:
                s += '              ~ ' + str(sng) + '\n'

        if self.bp_tree != None:
            s += 'bp_tree       = ' + str(self.bp_tree) + '\n'

        s += 'short_str     = '
        s += self.get_short_str() + '\n'

        s += 30 * '-' + '\n'
        return s
Beispiel #18
0
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)
Beispiel #19
0
    def test__get_genus( self ):

        pol = OrbRing.coerce( '(x1^2+x2^2+x3^2+3*x0^2)^2-16*(x1^2+x2^2)' )
        print( pol )

        os.environ['PATH'] += os.pathsep + '/home/niels/Desktop/n/app/maple/link/bin'
        try:
            sage_maple.eval( '1 + 1' )
            print( 'Maple is installed.' )
        except:
            print( 'Maple is NOT installed.' )
            gen = get_genus( pol )
            print( gen )
            assert gen == -3
            return

        gen = get_genus( pol )
        print( gen )
        assert gen == 1
Beispiel #20
0
    def test__get_factor_lst( self ):

        pol = OrbRing.coerce( '(x1-x0)^3*(x1-3*x0)^2*(x2^2+x3^2)' )
        print( pol )

        os.environ['PATH'] += os.pathsep + '/home/niels/Desktop/n/app/maple/link/bin'
        try:
            sage_maple.eval( 'with(algcurves);' )
            print( 'Maple is installed.' )
        except:
            print( 'Maple is NOT installed.' )
            fct_lst = get_factor_lst( pol )
            print( fct_lst )
            assert fct_lst == []
            return

        fct_lst = get_factor_lst( pol )
        print( fct_lst )
        assert str( fct_lst ) == "[('x2-RootOf(_Z^2+1)*x3', '1'), ('x2+RootOf(_Z^2+1)*x3', '1'), ('x0-1/3*x1', '2'), ('x0-x1', '3')]"
def quadric_smooth():
    '''
    Construct povray image of rulings on hyperboloid of one sheet.
    '''

    # construct the two rulings on the hyperboloid
    # by rotating lines L1 and L2
    c0, s0, c1, s1, t0 = OrbRing.coerce('c0,s0,c1,s1,t0')
    P = sage_vector([-2, -1, -0.5])
    Q = sage_vector([2, -1, -0.5])
    L0 = t0 * P + (t0 - 1) * Q
    L1 = t0 * Q + (t0 - 1) * P
    M = sage_matrix([(c1, s1, 0), (-s1, c1, 0), (0, 0, 1)])
    pmz_A_lst = [1] + list(M * L0)
    pmz_B_lst = [1] + list(M * L1)

    OrbTools.p('pmz_A_lst =', pmz_A_lst)
    for pmz in pmz_A_lst:
        OrbTools.p('\t\t', pmz)

    OrbTools.p('pmz_B_lst =', pmz_B_lst)
    for pmz in pmz_B_lst:
        OrbTools.p('\t\t', pmz)

    # PovInput ring cyclide
    #
    pin = PovInput()

    pin.path = './' + get_time_str() + '_quadric_smooth/'
    pin.fname = 'orb'
    pin.scale = 1
    pin.cam_dct['location'] = (0, -10, 0)
    pin.cam_dct['lookat'] = (0, 0, 0)
    pin.cam_dct['rotate'] = (0, 0, 0)
    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'] = 1.2

    pin.width = 400
    pin.height = 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, 0)
    pin.pmz_dct['FA'] = (pmz_A_lst, 0)
    pin.pmz_dct['FB'] = (pmz_B_lst, 0)

    v0_lst = [sage_QQ(i) / 10 for i in range(-15, 30, 5)]  # -15, 35
    v1_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 36)]
    v1_lst_F = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 2)]

    pin.curve_dct['A'] = {
        'step0': v0_lst,
        'step1': v1_lst,
        'prec': 10,
        'width': 0.1
    }
    pin.curve_dct['B'] = {
        'step0': v0_lst,
        'step1': v1_lst,
        'prec': 10,
        'width': 0.1
    }
    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
    }

    col_A = (0.5, 0.0, 0.0, 0.0)  # red
    col_B = rgbt2pov((28, 125, 154, 0))  # 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['FA'] = [True, (0.1, 0.1, 0.1, 0.0), 'phong 0.2 phong_size 5']
    pin.text_dct['FB'] = [True, (0.1, 0.1, 0.1, 0.0), 'phong 0.2 phong_size 5']

    # raytrace image/animation
    create_pov(pin, ['A', 'B', 'FA', 'FB'])
Beispiel #22
0
def get_mat(A_str, B_str, C_str):
    '''
    Parameters
    ----------
    A_str : string 
        
        A string of either one of the following forms:                            
        
            'O****'
            'tT'                  
            'T[#,#,#,#,#,#,#]'                   
            'R****[%,%,%,%]'                   
            'I'                   
            'P1'                  
            'P0'
            'M<list of a 9x9 matrix>'
            'E[$,$,$,$,$,$,$,$]'
            'E'
            'X[%,%,%]'
        
        where:                          
            
            *-symbol is a place holder for one of the following characters: 
              r,s,m,p,a                                       
            
            #-symbol denotes an element of "OrbRing.num_field".                     
            
            %-symbol denotes an integer in [0,360].
            
            $-symbol denotes an integer in [1,8] such that each
              integer occurs only 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.
                     
    B_str : string 
        Same specs as "A_str".
        
    C_str : string        
       Same specs as "A_str".  
    
    Returns
    -------
    sage_matrix
        Let matrix A over QQ[c0,s0,c1,s1] be defined as follows,
        where we make a case distinction on "A_str":
              
             "A_str[0] == 'O' " : "A = get_omat( A_str )".
             "A_str[0] == 'T' " : "A = get_tmat( A_str )".
             "A_str[0] == 'E' " : "A = get_emat( A_str )".
             "A_str[0] == 'X' " : "A = get_xmat( A_str )".  
             "A_str    == 'tT'" : "A = get_tmat('tT')".
             "A_str[0] == 'R' " : "A = get_rmat( A_str )".
             "A_str    == 'I' " : "A = sage_identity_matrix(9,9)".      
             "A_str    == 'P1'" : "A = get_pmat( True )".
             "A_str    == 'P0'" : "A = get_pmat( False )".
             "A_str[0] == 'M' " : "A = sage_matrix(<list of a matrix>)".
          
          Similarly, we obtain matrices B and C.          
          We return the matrix A*B*C.
    '''

    M_lst = []
    for M_str in [A_str, B_str, C_str]:

        if M_str[0] == 'O': M_lst += [get_omat(M_str)]
        elif M_str[0] == 'T': M_lst += [get_tmat(M_str)]
        elif M_str[0] == 'E': M_lst += [get_emat(M_str)]
        elif M_str[0] == 'X': M_lst += [get_xmat(M_str)]
        elif M_str == 'tT': M_lst += [get_tmat('tT')]
        elif M_str[0] == 'R': M_lst += [get_rmat(M_str)]
        elif M_str == 'I':
            M_lst += [sage_identity_matrix(OrbRing.num_field, 9, 9)]
        elif M_str == 'P1':
            M_lst += [get_pmat(True)]
        elif M_str == 'P0':
            M_lst += [get_pmat(False)]
        elif M_str[0] == 'M':
            mat_lst = OrbRing.coerce(M_str[1:])
            M_lst += [sage_matrix(mat_lst)]

    return M_lst[0] * M_lst[1] * M_lst[2]
Beispiel #23
0
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)
Beispiel #24
0
def get_curve_lst( pin, fam ):
    '''
    Parameters
    ----------
    pin : PovInput
        The following attributes of the PovInput object are used:
        * "pin.pmz_dct"
        * "pin.scale"
        * "pin.curve_dct"
        * "pin.curve_lst_dct"
                                         
    fam : string 
        A key string for a family id (eg. 'A').
        
    Returns
    -------
    list
        Returns a list of lists of points. Each list of points
        defines points on a curve. v1_lstD
        
        Returns "pin.curve_lst_dct[<fam>]"  if 
            "pin.curve_lst_dct[<fam>]!=None". 
    
        Otherwise let us assume w.l.o.g. that "fam=='A'"
        such that "pin.curve_lst_dct['A']==None".          
        
        We set "pin.curve_lst_dct['A']" as follows:
            pin.curve_lst_dct['A'] = [ <curveA<0>>, <curveA<1>>, ... ]            
        where           
          * <curveA<n>> is a list of points 
                [x,y,z] 
            on a curve in family with id 'A', which are 
            scaled with "pin.scale". 
          
          * The space between points in <curveA<n>> is 
            determined by "pin.curve_dct['A']['step0']".

          * The space between <curveA<n>> and <curveA<n+1>> is  
            determined by values in "pin.curve_dct['A']['step1']".

          * The precision of points in <curveA<n>> is 
            determined by values in "pin.curve_dct['A']['prec']".          
          
        Returns pin.curve_lst_dct['A'].
    '''

    OrbTools.p( fam )

    if fam in pin.curve_lst_dct and pin.curve_lst_dct[fam] != None:
        OrbTools.p( 'Already computed ', fam )
        return pin.curve_lst_dct[fam]

    pmz_lst, fam_id = pin.pmz_dct[fam]
    pmz_lst = OrbRing.coerce( pmz_lst )

    # loop through lists of parameter values
    pin.curve_lst_dct[fam] = []
    for v1 in pin.curve_dct[fam]['step1']:
        curve = []
        for v0 in pin.curve_dct[fam]['step0']:

            if fam_id == 0:
                point = get_pmz_value( pmz_lst, v0, v1, pin.curve_dct[fam]['prec'] )
            elif fam_id == 1:
                point = get_pmz_value( pmz_lst, v1, v0, pin.curve_dct[fam]['prec'] )
            else:
                raise ValueError( 'Expect pin.pmz_dct[fam][1] in [0,1]: ', fam_id )

            # add points to curve if map is defined
            if point != None:
                point = [ coord * pin.scale for coord in point  ]
                curve += [point]


        # need at least 3 points for cubic interpolation
        if len( curve ) >= 3:

            # add curve to family
            pin.curve_lst_dct[fam] += [curve]

    return pin.curve_lst_dct[fam]
Beispiel #25
0
    def test__get_deg_dim_3( self ):

        imp_lst = OrbRing.coerce( '[-x0^2+x1^2+x2^2+x3^2+x4^2+x5^2+x6^2+x7^2+x8^2, x8, x7, x6, x5, x1*x2-x0*x4]' )
        deg_dim = get_deg_dim( imp_lst )
        print( deg_dim )
        assert deg_dim == ( 4, 2 )
Beispiel #26
0
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'])
Beispiel #27
0
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'])
Beispiel #28
0
 def test__get_emb_dim( self ):
     imp_lst = OrbRing.coerce( '[-x0^2+x1^2+x2^2+x3^2+x4^2+x5^2+x6^2+x7^2+x8^2, x8, x7, x6, x5, x1*x2-x0*x4]' )
     emb = get_emb_dim( imp_lst )
     print( emb )
     assert emb == 3
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
Beispiel #30
0
    def test__get_deg_dim_2( self ):

        imp_lst = OrbRing.coerce( '[-x0^2+x1^2+x2^2+x3^2+x4^2+x5^2+x6^2+x7^2+x8^2, x8, x7, x6, x5, x4, x3]' )
        deg_dim = get_deg_dim( imp_lst )
        print( deg_dim )
        assert deg_dim == ( 2, 1 )