Exemple #1
0
    def __init__(self, convection_field, forcing_function):
        self._forcing_function = forcing_function
        self._convection_field = convection_field

        dx0 = sg.diff(convection_field[0], x)
        dx1 = sg.diff(convection_field[1], x)
        dy0 = sg.diff(convection_field[0], y)
        dy1 = sg.diff(convection_field[1], y)

        to_ccode = lambda u: sp.ccode(
            sympy.sympify(sg.symbolic_expression(u)._sympy_()))

        self._forcing_code = _forcing_template.format(
            **{'forcing_expr': to_ccode(forcing_function)})

        self._convection_code = _convection_template.format(**
            {'value0_expr': to_ccode(convection_field[0]),
             'value1_expr': to_ccode(convection_field[1]),
             'dx0_expr': to_ccode(dx0),
             'dx1_expr': to_ccode(dx1),
             'dy0_expr': to_ccode(dy0),
             'dy1_expr': to_ccode(dy1)})

        self.so_folder = tf.mkdtemp(prefix="cfem_") + os.sep
        # even if the object is not instantiated, we can still clean it up at
        # exit.
        atexit.register(lambda folder=self.so_folder: shutil.rmtree(folder))
        shutil.copy(_module_path + "makefile", self.so_folder)
        shutil.copy(_module_path + "cfem.h", self.so_folder)
        with open(self.so_folder + "funcs.c", 'w') as fhandle:
            fhandle.write("#include <math.h>\n")
            fhandle.write("#include \"cfem.h\"\n")
            fhandle.write(self._forcing_code)
            fhandle.write(self._convection_code)

        current_directory = os.getcwd()
        try:
            os.chdir(self.so_folder)
            util.run_make(command="autogenerated_functions")
            self.so = np.ctypeslib.load_library("libfuncs.so", "./")
            self.so.cf_forcing.restype = ct.c_double
            self.so.cf_forcing.argtypes = [ct.c_double, ct.c_double,
                                           ct.c_double]
            self.so.cf_convection.restype = CConvection
            self.so.cf_convection.argtypes = [ct.c_double, ct.c_double]
        finally:
            os.chdir(current_directory)
Exemple #2
0
def get_Fs23(F,w):
    Fs23 = 1440*diff(F,t2,t3).truncate(w+1) - 15120*diff(F,t4).truncate(w+1) - 60*diff(F,t0,t0,t3).truncate(w+1) - 120*diff(F,t0)._mul_trunc_(diff(F,t0,t3),w+1) - 72*diff(F,t0,t1,t2).truncate(w+1) - 72*diff(F,t1)._mul_trunc_(diff(F,t0,t2),w+1) - 72*diff(F,t1,t2)._mul_trunc_(diff(F,t0),w+1) + 90*diff(F,t1,t1).truncate(w+1) + 90*diff(F,t1).power_trunc(2,w+1) + 375*diff(F,t0,t2).truncate(w+1) + 360*diff(F,t2)._mul_trunc_(diff(F,t0),w+1) + 3*diff(F,t0,t0,t0,t1).truncate(w+1) + 6*diff(F,t0,t1)._mul_trunc_(diff(F,t0,t0),w+1) + 9*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t1),w+1) + 3*diff(F,t1)._mul_trunc_(diff(F,t0,t0,t0),w+1) + 6*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1) + 6*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t1),w+1) - 45*diff(F,t0,t0,t0).truncate(w+1)/8 - 65*diff(F,t0)._mul_trunc_(diff(F,t0,t0),w+1)/4 - 5*diff(F,t0).power_trunc(3,w+1) - 165*diff(F,t1).truncate(w+1)/2 + ZZ(29)/32
    return Fs23(z=1)
Exemple #3
0
def get_Fs6(F,w):
    Fs6 = 665280*diff(F, t6).truncate(w+1) - 1800*diff(F, t2, t2).truncate(w+1) - 1800*diff(F, t2)._mul_trunc_(diff(F, t2),w+1) - 5040*diff(F, t1, t3).truncate(w+1) - 5040*diff(F, t3)._mul_trunc_(diff(F, t1),w+1) - 15120*diff(F, t0, t4).truncate(w+1) - 15120*diff(F, t4)._mul_trunc_(diff(F, t0),w+1) + 16170*diff(F, t3).truncate(w+1) + 198*diff(F, t0, t1, t1).truncate(w+1) + 396*diff(F, t1)._mul_trunc_(diff(F, t0, t1),w+1) + 198*diff(F, t1, t1)._mul_trunc_(diff(F, t0),w+1) + 198*diff(F, t1).power_trunc(2,w+1)._mul_trunc_(diff(F, t0),w+1) + 330*diff(F, t0, t0, t2).truncate(w+1) + 330*diff(F, t2)._mul_trunc_(diff(F, t0, t0),w+1) + 660*diff(F, t0)._mul_trunc_(diff(F, t0, t2),w+1) + 330*diff(F, t2)._mul_trunc_(diff(F, t0),w+1)._mul_trunc_(diff(F, t0),w+1) - 33*diff(F, t0, t0, t0, t0).truncate(w+1)/8 - 33*diff(F, t0)._mul_trunc_(diff(F, t0, t0, t0),w+1)/2 - 99*diff(F, t0, t0)._mul_trunc_(diff(F, t0, t0),w+1)/8 - 99*diff(F, t0)._mul_trunc_(diff(F, t0),w+1)._mul_trunc_(diff(F, t0, t0),w+1)/4 - 33*diff(F, t0).power_trunc(4,w+1)/8 - 891*diff(F, t0, t1).truncate(w+1)/2 - 891*diff(F, t1)._mul_trunc_(diff(F, t0),w+1)/2 + 1155*diff(F, t0).truncate(w+1)/32
    return Fs6(z=1)
Exemple #4
0
def get_Zs22(Z):
    return ZZ(1)/2*(144*diff(Z,t2,t2) - 840*diff(Z,t3) - 12*diff(Z,t0,t0,t2) + 24*diff(Z,t0,t1) + diff(Z,t0,4)/4 - 3*diff(Z,t0))
Exemple #5
0
def get_Fs5(F,w):
    Fs5 = 30240*diff(F, t5).truncate(w+1) - 360*diff(F, t1, t2).truncate(w+1) - 360*diff(F, t2)._mul_trunc_(diff(F, t1),w+1) - 840*diff(F, t0, t3).truncate(w+1) - 840*diff(F, t0)._mul_trunc_(diff(F, t3),w+1) + 27*diff(F, t0, t0, t1).truncate(w+1) + 27*diff(F, t1)._mul_trunc_(diff(F, t0, t0),w+1) + 54*diff(F, t0)._mul_trunc_(diff(F, t0, t1),w+1) + 27*diff(F, t1)._mul_trunc_(diff(F, t0).power_trunc(2,w+1),w+1) + 585*diff(F, t2).truncate(w+1) - 105*diff(F, t0, t0).truncate(w+1)/8 - 105*diff(F, t0).power_trunc(2,w+1)/8
    return Fs5(z=1)
Exemple #6
0
def get_Fs24(F,w):
    Fs24 = 385*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)/8 + 385*diff(F,t0,t0).truncate(w+1)/8 - 21*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0,t0),w+1)/4 - 7*diff(F,t0)._mul_trunc_(diff(F,t0,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1) - 7*diff(F,t0,t0,t0,t0,t0).truncate(w+1)/12 - 147*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t1),w+1) - 637*diff(F,t0,t0,t1).truncate(w+1)/4 + 102*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t2),w+1) + 18*diff(F,t0,t1)._mul_trunc_(diff(F,t0,t1),w+1) - 7*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1)/2 + 60*diff(F,t2)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1) - 35*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t0,t0),w+1)/12 - 21*diff(F,t0,t0)._mul_trunc_(diff(F,t0,t0,t0),w+1)/4 - 637*diff(F,t0)._mul_trunc_(diff(F,t0,t1),w+1)/2 + 36*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t1),w+1) + 132*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t2),w+1) + 30*diff(F,t2)._mul_trunc_(diff(F,t0,t0,t0),w+1) + 102*diff(F,t0,t2)._mul_trunc_(diff(F,t0,t0),w+1) + 18*diff(F,t0)._mul_trunc_(diff(F,t0,t1,t1),w+1) + 18*diff(F,t1)._mul_trunc_(diff(F,t0,t0,t1),w+1) - 720*diff(F,t0,t2)._mul_trunc_(diff(F,t2),w+1) - 1680*diff(F,t0)._mul_trunc_(diff(F,t0,t4),w+1) - 720*diff(F,t2,t2)._mul_trunc_(diff(F,t0),w+1) - 432*diff(F,t1,t2)._mul_trunc_(diff(F,t1),w+1) - 720*diff(F,t0,t2,t2).truncate(w+1) - 840*diff(F,t0,t0,t4).truncate(w+1) + 44*diff(F,t2,t0,t0,t0).truncate(w+1) + 20160*diff(F,t2,t4).truncate(w+1) - 216*diff(F,t1,t1,t2).truncate(w+1) - 147*diff(F,t1)._mul_trunc_(diff(F,t0,t0),w+1) + 9*diff(F,t1,t1,t0,t0).truncate(w+1) + 2520*diff(F,t2)._mul_trunc_(diff(F,t1),w+1) + 6720*diff(F,t0)._mul_trunc_(diff(F,t3),w+1) + 6720*diff(F,t0,t3).truncate(w+1) - 2835*diff(F,t2).truncate(w+1) + 2814*diff(F,t1,t2).truncate(w+1) - 332640*diff(F,t5).truncate(w+1)
    return Fs24(z=1)
Exemple #7
0
def get_Fs22(F,w):
    Fs22 = ZZ(1)/2*(144*diff(F,t2,t2).truncate(w+1) - 840*diff(F,t3).truncate(w+1) - 12*diff(F,t0,t0,t2).truncate(w+1) - 24*diff(F,t0)._mul_trunc_(diff(F,t0,t2),w+1) + 24*diff(F,t0,t1).truncate(w+1) + 24*diff(F,t1)._mul_trunc_(diff(F,t0),w+1) + diff(F,t0,t0,t0,t0).truncate(w+1)/4 + diff(F,t0)._mul_trunc_(diff(F,t0,t0,t0),w+1) + diff(F,t0,t0).power_trunc(2,w+1)/2 + diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t0),w+1) - 3*diff(F,t0).truncate(w+1))
    return Fs22(z=1)
Exemple #8
0
def get_Fs3(F,w):
    Fs3 = 120*diff(F,t3).truncate(w+1) - 6*diff(F,t0,t1).truncate(w+1) - 6*diff(F,t1)._mul_trunc_(diff(F,t0),w+1) + 5*diff(F,t0).truncate(w+1)/4
    return Fs3(z=1)
Exemple #9
0
def get_Zs3(Z):
    return 120*diff(Z,t3) - 6*diff(Z,t0,t1) + 5*diff(Z,t0)/4
Exemple #10
0
def get_Fs2(F,w):
    Fs2 = 12*diff(F,t2).truncate(w+1) - diff(F,t0,t0).truncate(w+1)/2 - diff(F,t0)._mul_trunc_(diff(F,t0),w+1)/2
    return Fs2(z=1)
Exemple #11
0
def get_Zs2(Z):
    return 12*diff(Z,t2) - diff(Z,t0,2)/2
Exemple #12
0
def get_Fs222(F,w):
    Fs222 = ZZ(1)/6*(1728*diff(F,t2,t2,t2).truncate(w+1) - 30240*diff(F,t2,t3).truncate(w+1) - 216*diff(F,t0,t0,t2,t2).truncate(w+1) - 432*diff(F,t0,t2).power_trunc(2,w+1) - 432*diff(F,t0)._mul_trunc_(diff(F,t0,t2,t2),w+1) + 864*diff(F,t0,t1,t2).truncate(w+1) + 864*diff(F,t1)._mul_trunc_(diff(F,t0,t2),w+1) + 864*diff(F,t1,t2)._mul_trunc_(diff(F,t0),w+1) + 1260*diff(F,t0,t0,t3).truncate(w+1) + 2520*diff(F,t0)._mul_trunc_(diff(F,t0,t3),w+1) + 9*diff(F,t0,t0,t0,t0,t2).truncate(w+1) + 36*diff(F,t0,t2)._mul_trunc_(diff(F,t0,t0,t0),w+1) + 36*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t0,t2),w+1) + 36*diff(F,t0,t0)._mul_trunc_(diff(F,t0,t0,t2),w+1) + 72*diff(F,t0)._mul_trunc_(diff(F,t0,t2),w+1)._mul_trunc_(diff(F,t0,t0),w+1) + 36*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t0,t2),w+1) + 151200*diff(F,t4).truncate(w+1) - 576*diff(F,t1,t1).truncate(w+1) - 576*diff(F,t1).power_trunc(2,w+1) - 2628*diff(F,t0,t2).truncate(w+1) - 2520*diff(F,t2)._mul_trunc_(diff(F,t0),w+1) - 36*diff(F,t0,t0,t0,t1).truncate(w+1) - 108*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t1),w+1) - 36*diff(F,t1)._mul_trunc_(diff(F,t0,t0,t0),w+1) - 72*diff(F,t0,t1)._mul_trunc_(diff(F,t0,t0),w+1) - 72*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1) - 72*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t1),w+1) - diff(F,t0,t0,t0,t0,t0,t0).truncate(w+1)/8 - 3*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t0,t0,t0),w+1)/4 - 3*diff(F,t0,t0)._mul_trunc_(diff(F,t0,t0,t0,t0),w+1)/2 - 5*diff(F,t0,t0,t0).power_trunc(2,w+1)/4 - 6*diff(F,t0)._mul_trunc_(diff(F,t0,t0),w+1)._mul_trunc_(diff(F,t0,t0,t0),w+1) - diff(F,t0,t0).power_trunc(3,w+1) - 3*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t0,t0,t0),w+1)/2 - 3*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t0).power_trunc(2,w+1),w+1) - diff(F,t0).power_trunc(3,w+1)._mul_trunc_(diff(F,t0,t0,t0),w+1) + 63*diff(F,t0,t0,t0).truncate(w+1)/2 + 90*diff(F,t0)._mul_trunc_(diff(F,t0,t0),w+1) + 27*diff(F,t0).power_trunc(3,w+1) + 378*diff(F,t1).truncate(w+1) - ZZ(63)/20)
    return Fs222(z=1)
Exemple #13
0
def get_Fs7(F,w):
    Fs7 = 17297280*diff(F,t7).truncate(w+1) - 50400*diff(F,t2,t3).truncate(w+1) - 50400*diff(F,t3)._mul_trunc_(diff(F,t2),w+1) - 90720*diff(F,t1,t4).truncate(w+1) - 90720*diff(F,t4)._mul_trunc_(diff(F,t1),w+1) - 332640*diff(F,t0,t5).truncate(w+1) - 332640*diff(F,t5)._mul_trunc_(diff(F,t0),w+1) + 468*diff(F,t1,t1,t1).truncate(w+1) + 1404*diff(F,t1)._mul_trunc_(diff(F,t1,t1),w+1) + 468*diff(F,t1).power_trunc(3,w+1) + 4680*diff(F,t0,t1,t2).truncate(w+1) + 4680*diff(F,t1)._mul_trunc_(diff(F,t0,t2),w+1) + 4680*diff(F,t2)._mul_trunc_(diff(F,t0,t1),w+1) + 4680*diff(F,t1,t2)._mul_trunc_(diff(F,t0),w+1) + 4680*diff(F,t2)._mul_trunc_(diff(F,t1),w+1)._mul_trunc_(diff(F,t0),w+1) + 5460*diff(F,t0,t0,t3).truncate(w+1) + 5460*diff(F,t3)._mul_trunc_(diff(F,t0,t0),w+1) + 10920*diff(F,t0)._mul_trunc_(diff(F,t0,t3),w+1) + 5460*diff(F,t3)._mul_trunc_(diff(F,t0),w+1).power_trunc(2,w+1) + 507780*diff(F,t4).truncate(w+1) - 10725*diff(F,t0,t2).truncate(w+1) - 10725*diff(F,t2)._mul_trunc_(diff(F,t0),w+1) - 5577*diff(F,t1,t1).truncate(w+1)/2 - 5577*diff(F,t1).power_trunc(2,w+1)/2 - 143*diff(F,t0,t0,t0,t1).truncate(w+1) - 143*diff(F,t1)._mul_trunc_(diff(F,t0,t0,t0),w+1) - 429*diff(F,t0,t1)._mul_trunc_(diff(F,t0,t0),w+1) - 429*diff(F,t0)._mul_trunc_(diff(F,t0,t0,t1),w+1) - 429*diff(F,t0).power_trunc(2,w+1)._mul_trunc_(diff(F,t0,t1),w+1) - 429*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t0),w+1) - 143*diff(F,t1)._mul_trunc_(diff(F,t0),w+1).power_trunc(3,w+1) + 1001*diff(F,t0,t0,t0).truncate(w+1)/8 + 3003*diff(F,t0)._mul_trunc_(diff(F,t0,t0),w+1)/8 + 1001*diff(F,t0).power_trunc(3,w+1)/8 + 27027*diff(F,t1).truncate(w+1)/16 - ZZ(5005)/384
    return Fs7(z=1)
Exemple #14
0
def get_Fs33(F,w):
    Fs33 = ZZ(1)/2*(14400*diff(F,t3,t3).truncate(w+1) - 332640*diff(F,t5).truncate(w+1) - 1440*diff(F,t0,t1,t3).truncate(w+1) - 1440*diff(F,t1,t3)._mul_trunc_(diff(F,t0),w+1) - 1440*diff(F,t0,t3)._mul_trunc_(diff(F,t1),w+1) + 7020*diff(F,t0,t3).truncate(w+1) + 6720*diff(F,t0)._mul_trunc_(diff(F,t3),w+1) + 2160*diff(F,t1,t2).truncate(w+1) + 2160*diff(F,t2)._mul_trunc_(diff(F,t1),w+1) + 36*diff(F,t1,t1,t0,t0).truncate(w+1) + 36*diff(F,t1,t0)._mul_trunc_(diff(F,t1,t0),w+1) + 36*diff(F,t1,t1)._mul_trunc_(diff(F,t0,t0),w+1) + 72*diff(F,t1)._mul_trunc_(diff(F,t0,t0,t1),w+1) + 72*diff(F,t0)._mul_trunc_(diff(F,t0,t1,t1),w+1) + 36*diff(F,t1)._mul_trunc_(diff(F,t1),w+1)._mul_trunc_(diff(F,t0,t0),w+1) + 72*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0,t1),w+1) + 36*diff(F,t1,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0),w+1) - 2400*diff(F,t2).truncate(w+1) - 165*diff(F,t0,t0,t1).truncate(w+1) - 165*diff(F,t1)._mul_trunc_(diff(F,t0,t0),w+1) - 150*diff(F,t1)._mul_trunc_(diff(F,t0),w+1)._mul_trunc_(diff(F,t0),w+1) - 315*diff(F,t0)._mul_trunc_(diff(F,t0,t1),w+1) + 725*diff(F,t0,t0).truncate(w+1)/16 + 175*diff(F,t0)._mul_trunc_(diff(F,t0),w+1)/4)
    return Fs33(z=1)
    def derivation(self, element):
        r'''
            Computes the derivation of an element.

            This method catchs the essence of a :class:`DiffPolynomialRing`: the extension
            of the derivation on the base ring (retrieved by ``self.base()``) to the 
            infinite polynomial ring in such a way that the variables are linked linearly with the 
            derivation.

            For element in the base ring, this method relies on the Sage method :func:`diff`.

            INPUT:

            * ``element``: an object. Must be included in ``self``. 

            OUTPUT:

            An element in ``self`` that represents the derivative of ``element``.

            EXAMPLES::

                sage: from dalgebra.differential_polynomial.differential_polynomial_ring import * 
                sage: R.<y> = DiffPolynomialRing(QQ['x']); x = R.base().gens()[0]
                sage: R.derivation(y[0])
                y_1
                sage: R.derivation(x)
                1
                sage: R.derivation(x*y[10])
                x*y_11 + y_10
                sage: R.derivation(x^2*y[1]^2 - y[2]*y[1])
                -y_3*y_1 - y_2^2 + 2*x^2*y_2*y_1 + 2*x*y_1^2

            This derivation also works naturally with several infinite variables::

                sage: S = DiffPolynomialRing(R, 'a'); a,y = S.gens()
                sage: S.derivation(a[1] + y[0]*a[0])
                a_1*y_0 + a_0*y_1 + a_2
        '''
        if (element in self):
            element = self(element)
        else:
            element = self(str(element))

        if (element in self.base()):
            return self.base()(diff(self.base()(element)))

        if (not element in self.__cache_derivatives):
            generators = self.gens()
            if (element.is_monomial()):
                c = element.coefficients()[0]
                m = element.monomials()[0]
                v = element.variables()
                d = [element.degree(v[i]) for i in range(len(v))]
                v = [self(str(el)) for el in v]
                base = c * prod([v[i]**(d[i] - 1)
                                 for i in range(len(v))], self.one())

                first_term = self.derivation(c) * self(str(m))
                second_term = self.zero()
                for i in range(len(v)):
                    to_add = d[i] * prod(
                        [v[j] for j in range(len(v)) if j != i], self.one())
                    for g in generators:
                        if (g.contains(v[i])):
                            to_add *= g[g.index(v[i]) + 1]
                            break
                    second_term += to_add
                self.__cache_derivatives[
                    element] = first_term + base * second_term
            else:
                c = element.coefficients()
                m = [self(str(el)) for el in element.monomials()]
                self.__cache_derivatives[element] = sum(
                    self.derivation(c[i]) * m[i] + c[i] * self.derivation(m[i])
                    for i in range(len(m)))

        return self.__cache_derivatives[element]
Exemple #16
0
def get_Fs4(F,w):
    Fs4 = 1680*diff(F, t4).truncate(w+1) - 18*diff(F, t1, t1).truncate(w+1) - 18*diff(F, t1).power_trunc(2,w+1) - 60*diff(F, t0, t2).truncate(w+1) - 60*diff(F, t2)._mul_trunc_(diff(F, t0),w+1) + 7*diff(F, t0, t0, t0).truncate(w+1)/6 + 7*diff(F, t0)._mul_trunc_(diff(F, t0, t0),w+1)/2 + 7*diff(F, t0).power_trunc(3,w+1)/6 + 49*diff(F, t1).truncate(w+1)/2 - ZZ(35)/96
    return Fs4(z=1)
    def eval(self, element, *args, **kwds):
        r'''
            Method to evaluate elements in the ring of differential polynomials.

            Since the differential polynomials have an intrinsic meaning (namely, the 
            variables are related by derivation), evaluating a differential polynomial
            is a straight-forward computation once the objects for the ``*_0`` term is given.

            This method evaluates elements in ``self`` following that rule.

            INPUT:

            * ``element``: element (that must be in ``self``) to be evaluated
            * ``args``: list of arguments that will be linearly related with the generators
              of ``self`` (like they are given by ``self.gens()``)
            * ``kwds``: dictionary for providing values to the generators of ``self``. The 
              name of the keys must be the names of the generators (as they can be got using 
              the attribute ``_name``).

            We allow a mixed used of ``args`` and ``kwds`` but an error will be raised if

            * There are too many arguments in ``args``,
            * An input in ``kwds`` is not a valid name of a generator,
            * There are duplicate entries for a generator.

            OUTPUT:

            The resulting element after evaluating the variable `\alpha_n = \partial^n(\alpha)`,
            where `\alpha` is the name of the generator.

            EXAMPLES::

                sage: from dalgebra.differential_polynomial.differential_polynomial_ring import * 
                sage: R.<y> = DiffPolynomialRing(QQ['x']); x = R.base().gens()[0]
                sage: R.eval(y[1], 0)
                0
                sage: R.eval(y[0] + y[1], x)
                x + 1
                sage: R.eval(y[0] + y[1], y=x)
                x + 1

            This method commutes with the use of :func:`derivation`::

                sage: R.eval(R.derivation(x^2*y[1]^2 - y[2]*y[1]), y=x) == R.derivation(R.eval(x^2*y[1]^2 - y[2]*y[1], y=x))
                True

            This evaluation also works naturally with several infinite variables::

                sage: S = DiffPolynomialRing(R, 'a'); a,y = S.gens()
                sage: S.eval(a[1] + y[0]*a[0], a=x, y=x^2)
                x^3 + 1
                sage: in_eval = S.eval(a[1] + y[0]*a[0], y=x); in_eval
                a_1 + x*a_0
                sage: parent(in_eval)
                Ring of differential polynomials in (a) over [Univariate Polynomial Ring in x over Rational Field]
        '''
        if (not element in self):
            raise TypeError("Impossible to evaluate %s as an element of %s" %
                            (element, self))
        g = self.gens()
        final_input = {}
        names = [el._name for el in g]
        if (len(args) > self.ngens()):
            raise ValueError(
                "Too many argument for evaluation: given %d, expected (at most) %d"
                % (len(args), self.ngens()))
        for i in range(len(args)):
            final_input[g[i]] = args[i]
        for key in kwds:
            if (not key in names):
                raise TypeError("Invalid name for argument %s" % key)
            gen = g[names.index(key)]
            if (gen in final_input):
                raise TypeError("Duplicated value for generator %s" % gen)
            final_input[gen] = kwds[key]

        max_derivation = {gen: 0 for gen in final_input}
        for v in element.variables():
            for gen in max_derivation:
                if (gen.contains(v)):
                    max_derivation[gen] = max(max_derivation[gen],
                                              gen.index(v))
                    break

        to_evaluate = {}
        for gen in max_derivation:
            for i in range(max_derivation[gen] + 1):
                to_evaluate[str(gen[i])] = diff(final_input[gen], i)

        ## Computing the final ring
        values = list(final_input.values())
        R = parent(values[0])
        for i in range(1, len(values)):
            R = pushout(R, parent(values[i]))

        poly = element.polynomial()
        ## Adding all the non-appearing variables on element
        if (len(final_input) == len(g)):
            for v in poly.parent().gens():
                if (v not in poly.variables()) and (not str(v) in to_evaluate):
                    to_evaluate[str(v)] = 0
        else:
            left_gens = [gen for gen in g if gen not in final_input]
            R = DiffPolynomialRing(R, [el._name for el in left_gens])
            for v in poly.parent().gens():
                if (not any(gen.contains(v)
                            for gen in left_gens)) and (not str(v)
                                                        in to_evaluate):
                    to_evaluate[str(v)] = 0

        return R(poly(**to_evaluate))
Exemple #18
0
 def memo_Nlocal(g, n, stratum, labeled, mode):
     #print('Computing for (%s,%s,%s)...Cache size %s' % (g,n,stratum,len(cache_poly)))
     if not stratum or n != 2 - 2 * g + 1 / ZZ(2) * sum(
             stratum) or g < 0 or n < 1:
         return B.zero()
     if type(stratum) == list: stratum = tuple(stratum)
     if (g, n, stratum) in cache_poly:
         if labeled: return cache_poly[(g, n, stratum)]
         else:
             return cache_poly[(g, n, stratum)] / cache_labeling[(g, n,
                                                                  stratum)]
     if not labeled:
         memo_Nlocal(g, n, stratum, True, mode)
         return cache_poly[(g, n, stratum)] / cache_labeling[(g, n,
                                                              stratum)]
     #weight_check(g,n,stratum)
     m = [
         stratum.count(2 * i - 1)
         for i in range((max(stratum) + 1) / ZZ(2) + 1)
     ]
     if -1 in stratum:  # case with poles
         elderstratum = list(stratum)
         elderstratum.remove(-1)
         elderstratum.append(1)
         N_lab = memo_Nlocal(g, n + 1, elderstratum, True,
                             mode)(*vanish(b, [n + 1]))
         for i in range(len(elderstratum)):
             if elderstratum[i] > 1:
                 newstratum = list(elderstratum)
                 newstratum[i] = newstratum[i] - 2
                 N_lab -= elderstratum[i] * memo_Nlocal(
                     g, n, newstratum, True, mode)
         N_lab *= ZZ(1) / elderstratum.count(1)
         cache_poly[(g, n, stratum)] = N_lab
         cache_labeling[(g, n, stratum)] = ZZ(
             prod(
                 factorial(stratum.count(i))
                 for i in range(-1,
                                max(stratum) + 1)))
         return cache_poly[(g, n, stratum)]
     elif mode == 'derivative' or len(m) == 2:  # case without poles
         _Fs = stratum_to_F(g, n, stratum)
         deg = ZZ(3 * g - 3 + n - 1 / 2 * sum(d - 1 for d in stratum))
         M = sum(m[i] * (i - 1) for i in range(len(m)))
         mondeg = Partitions(deg + n, length=n)
         const = 2**(5 * g - 6 + 2 * n - 2 * M)
         labeling = prod(
             factorial(stratum.count(i))
             for i in range(1,
                            max(stratum) + 1))
         N_lab = ZZ(1)/const*labeling*sum(prod(ZZ(1)/factorial(d-1) for d in par)*\
                         prod(factorial(i) for i in par.to_exp())*\
                         _Fs.monomial_coefficient(prod(T.gen(d-1) for d in par))*\
                         sum(prod(B.gen(j)**(2*(sympar[j]-1)) for j in range(n)) for sympar in Permutations(par))\
                         for par in mondeg)
         cache_poly[(g, n, stratum)] = N_lab
         cache_labeling[(g, n, stratum)] = ZZ(
             prod(
                 factorial(stratum.count(i))
                 for i in range(-1,
                                max(stratum) + 1)))
         return cache_poly[(g, n, stratum)]
     elif mode == 'recursive':
         assert m[2] == 1 and len(
             m
         ) == 3, "'recursive' mode is only available for stratum = [3,1,1,...,-1,-1]"
         first_term = 2**4 * diff(
             memo_Nlocal(g, n + 1, [1] * (m[1] + 5), False, mode), b[n],
             4)(*vanish(b, [n + 1]))
         second_term = -ZZ(1) / 2 * 2 * memo_Nlocal(
             g - 1, n + 2, [1] *
             (m[1] + 3), False, mode)(*vanish(b, [n + 1, n + 2]))
         third_term = 0
         for par in OrderedSetPartitions(b[:n], 2):
             n_1, n_2 = len(par[0]), len(par[1])
             assert n_1 + n_2 == n
             third_term += -ZZ(1)/2*sum(memo_Nlocal(g_1,n_1+1,[1]*(4*g_1-4+2*(n_1+1)),False,mode)(*list(par[0])+[0]*(30-n_1))\
                     *memo_Nlocal(g-g_1,n_2+1,[1]*(4*(g-g_1)-4+2*(n_2+1)),False,mode)(*list(par[1])+[0]*(30-n_2))\
                               for g_1 in range(g+1))
         N_unlab = first_term + second_term + third_term
         cache_labeling[(g, n, stratum)] = ZZ(
             prod(
                 factorial(stratum.count(i))
                 for i in range(-1,
                                max(stratum) + 1)))
         cache_poly[(g, n,
                     stratum)] = N_unlab * cache_labeling[(g, n, stratum)]
         return cache_poly[(g, n, stratum)]