# generate his own symbolic math function

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 close merge delete

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 ! ;-)

( 2019-10-09 06:34:07 -0500 )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)

( 2019-10-10 10:39:50 -0500 )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))

( 2019-10-10 11:09:31 -0500 )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))

( 2019-10-12 09:18:28 -0500 )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.

( 2019-10-12 21:46:02 -0500 )edit

Sort by » oldest newest most voted

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).

more