Ask Your Question
0

generate his own symbolic math function

asked 2019-10-09 13:10:37 +0200

ortollj gravatar image

updated 2019-10-09 20:37:59 +0200

Hi

If I would like to generate my own symbolic math function : general_falling_factorial(x, j, n) . What I should add and modify in the code below ? (I do not know what to do with the two lines below I know it is ok for the first one, but what must I write for the second one ?)

   return prod((((x)-(k*(j))) for k in (0..(n-1))), z=x.parent().one())
return prod((((x)-(k*(j))) for k in (0..(n-1))), z=x.parent().one())

code on sageCell

j,n=var('j,n')
N=11


show(LatexExpr(r"B_n=\sum_{j=1}^{n+1}\frac{(-1)^{j-1}}{j}{n+1\choose j}\sum_{i=0}^{j-1}(i|j)_n"))
show(LatexExpr(r"\text{with }\, \,(i|j)_n:=i(i-j)\cdots(i-(n-1)j)= \
                \text{general_falling_factorial() is not the falling_factorial() SageMath Function} \
                \, = \, "),falling_factorial(x, n))


print "https://math.stackexchange.com/questions/497616/is-there-an-explicit-formula-for-the-bernoulli-numbers-that-doesnt-implicitly-r"
print "http://youngp.people.cofc.edu/factbern.pdf"

show(LatexExpr(r"B_n=\sum_{j=1}^{n+1}\frac{(-1)^{j-1}}{j}{n+1\choose j}\sum_{i=0}^{j-1}(i|j)_n"))
show(LatexExpr(r"\text{with }\, \,(i|j)_n:=i(i-j)\cdots(i-(n-1)j)"))




def general_falling_factorial_latex(self, x,j,n):
    return '{' + '('+str(x) + ' | ' + str(j) + ')'+'}_{' + str(n) + '}'
general_falling_factorial = function('general_falling_factorial', nargs=3, print_latex_func=general_falling_factorial_latex)



def general_falling_factorial(x, j, n):
    r""" to fill up """

    from sage.symbolic.expression import Expression
    from sage.structure.coerce import py_scalar_to_element
    x = py_scalar_to_element(x)
    j = py_scalar_to_element(j)
    n = py_scalar_to_element(n)

    if ((isinstance(j, Integer) or
        (isinstance(j, Expression) and
        j.is_integer())) and j >= 0) and \
        ((isinstance(n, Integer) or
        (isinstance(n, Expression) and
        n.is_integer())) and n >= 0)   :
        return prod((((x)-(k*(j))) for k in (0..(n-1))), z=x.parent().one())


    return prod((((x)-(k*(j))) for k in (0..(n-1))), z=x.parent().one())

def bernoulliExplicit(N) :
    bernoulliSL=[]
    for n in range(0,N) :
        bernoulliSLt=[]
        for j in range (1,n+2):
            #show("j : ",j)
            bernoulliSLt.append((((-1)^(j-1)/j) *(factorial(n+1))/((factorial(j)*(factorial((n+1-j))))))* \
                                sum([general_falling_factorial(i,j,n) for i in range(0,j)]))
        bernoulliSL.append(sum(bernoulliSLt))
    return bernoulliSL
show("Explicit Bernoulli List : ",bernoulliExplicit(N))


bernoulliL=[]
for i in range(0,N) :
    bernoulliL.append(bernoulli(i))


show("SageMath Bernoulli List : ",bernoulliL)
edit retag flag offensive close merge delete

Comments

In my attempt to generate my own general_falling_factorial, I simply copy and slightly modified falling_factorial() .

I suppose it is a naive way ! ;-)

ortollj gravatar imageortollj ( 2019-10-09 13:34:07 +0200 )edit

Hello, @ortollj. Could you please define what you mean by "symbolic function"? Concerning the returns in your code, the first one and the second one are exactly the same, so the if statement in the middle of the definition is useless. Also, the use of the z argument makes it equal to $1$, meaning multiply by $1$, which is useless. On the other hand, the py_scalar_to_element function seems to do exactly the same job as the Sage preparser: it transforms 42 into Integer(42), 2,3 into RealNumber('2.3'), etc. Using this function should be unnecessary in 99.9% of the cases. Finally, there are unnecessary parenthesis.

I would rewrite the function as follows (see next comment)

dsejas gravatar imagedsejas ( 2019-10-10 17:39:50 +0200 )edit

Sorry, I run out of space. Here is the code:

def general_falling_factorial(x, j, n):
    r""" to fill up """
    # I think j<0 or n<0 is not acceptable, so...
    if (j < 0) or (n < o):
        raise RuntimeError('j and n should be nonegative')
    return prod(x-k*j for k in (0..n-1))
dsejas gravatar imagedsejas ( 2019-10-10 18:09:31 +0200 )edit

I think I did not express myself well, (but maybe my question does not make sense?)

what I asked was simply to get the same displayed thing when I call :

show(general_falling_factorial(x,j,n))

with only symbolics variables x,j,n as if I call

show(general_falling_factorial_latex(x,j,n))
ortollj gravatar imageortollj ( 2019-10-12 16:18:28 +0200 )edit
1

Hello, @ortollj. Sorry about the misunderstanding. I am still not sure, but does this code is what you are looking for? It can evaluate the function numerically, and has a LaTeX representation.

I am deleting my previous answer. If this code is correct, I'll add it as answer.

dsejas gravatar imagedsejas ( 2019-10-13 04:46:02 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2019-10-15 00:22:33 +0200

dsejas gravatar image

Hello, @ortollj! You have to define two functions: one to take care of the numeric evaluation, and the other for taking care of the LaTeX representation. The important thing is that you LaTeX output function must return a LatexExpr string. Let me explain.

First, we define the numeric evaluation function:

def general_falling_factorial_numeric(self, x, j, n, parent=None, algorithm=None):
    r""" to fill up """
    if (j < 0) or (n < 0):
        raise RuntimeError('j and n should be nonnegative!')
    return int(prod(x-k*j for k in (0..n-1)))

Notice the signature of the function? I have used self, parent=None and algorithm=None. I am not completely sure why these are needed in this case of defining symbolic functions, but they are. Maybe you could post a question about this if you are interested.

Now, we define the LaTeX function:

def general_falling_factorial_latex(self, x, j, n):
    return LatexExpr('{' + '('+str(x) + ' | ' + str(j) + ')'+'}_{' + str(n) + '}')

Notice that this function doesn't only return a string, but it encloses it in a LatexExpr type, which is what is rendered as LaTeX output by the show function (below). If you don't use that, you will get only a non-LaTeX string.

Finally, we have to put both functions under the same name:

general_falling_factorial = function('general_falling_factorial', nargs=3, evalf_func=general_falling_factorial_numeric, print_latex_func=general_falling_factorial_latex)

This new function is called general_falling factorial, and you can call it in your code by that name. Besides defining a name for the function, I have indicated that it takes three arguments with nargs=3. The argument evalf_funcspecifies what subroutine should be called when you want a numerical result (general_falling_factorial_numeric, in this case). The argument print_latex_func specifies what subroutine to call when you want LaTeX output (general_falling_factorial_latex, in this case).

Now you can use your new function to compute a result like:

general_falling_factorial(2, 1, 1).n()

which returns 2 (I used int in the first subroutine to return integers only). The .n() part tells Sage that you want a numeric result, so it calls general_falling_factorial_numeric.

On the other hand, you can also obtain a LaTeX output with

var('x j n')
general_falling_factorial(x, j, n).show()

which will return $(x | j)_n$. The .show() part indicates Sage that you want a LaTeX output, so it has to call general_falling_factorial_latex.

Finally, if you don't use .n() nor .show(), you will get a purely symbolic result:

general_falling_factorial(2, 1, 1)

returns general_falling_factorial(2, 1, 1).

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-10-09 13:10:37 +0200

Seen: 306 times

Last updated: Oct 15 '19