Bessel functions

i like this post (click again to cancel)
0
i dont like this post (click again to cancel)

A couple of questions about Bessel functions:

(1) Shouldn't this return return a symbolic expression, so that it can be used as part of an expression to be evaluated later with a specific r:

sage: var('r')
sage: bessel_J(0,r)

I'm thinking specifically of building up a series that will later be plotted.

(2) There was talk a while back about making the zeros of the Bessel functions available without having to calculate them with find_root() (Not that there's a problem doing that, but it would just be a convenience.) I was just wondering if anything came of that.

asked Jan 16 '11

Mike Witt gravatar image Mike Witt
455 4 11 26

updated Jun 16 '11

Kelvin Li gravatar image Kelvin Li
423 9 16

2 Answers:

i like this answer (click again to cancel)
1
i dont like this answer (click again to cancel)

(1) Yep, it should return something symbolic, but unfortunately it doesn't right now. Some relevant tickets are #4102 and #7636 (see the referenced thread). I'll try to make it a priority to get that done for 4.6.2.

(2) I don't think anything's been done with that yet either. mpmath provides efficient numerical evaluation of the zeros (see here ). It should be easy to make a symbolic wrapper around that. I've made this #10636.

link

posted Jan 16 '11

Mike Hansen gravatar image Mike Hansen flag of United States
3675 19 43 81
OK, thanks. Like I mentioned #2 is just a convenience. But #1 really had me stumped. I do see that there appears to be an explanation of how to create a symbolic function in one of those threads, and I'll try that out. Mike Witt (Jan 16 '11)
FWIW, I can't seem to get the barebones example of a symbolic bessel_J from the above thread working. But I do look forward to any progress on those two tickets. They seem to apply far beyond this one particular issue. Mike Witt (Jan 16 '11)
i like this answer (click again to cancel)
1
i dont like this answer (click again to cancel)

Just as a follow up to this. Since, even though creating a symbolic function is "easy", it wasn't easy (for me) to locate the information on how to do it. So just in case someone else might benefit from this, I thought I'd post the following examples which work on Sage 4.6.

Here's a simple definition of a symbolic Bessel J:

----------------------------------------------------------------------
| Sage Version 4.6, Release Date: 2010-10-30                         |
| Type notebook() for the GUI, and license() for information.        |
----------------------------------------------------------------------
sage: from sage.symbolic.function_factory import function_factory
sage: def j_eval(self, m, z, parent=None): return(bessel_J(m,z))
....: 
sage: BesselJ = function_factory( name='BesselJ', nargs=2, evalf_func=j_eval)
sage: 
sage: var('m,z')
(m, z)
sage: BesselJ(m,z)
BesselJ(m, z)
sage: 
sage: integral_numerical(BesselJ(0,z),0,1)
(0.91973041008976042, 1.0211058777295894e-14)
sage: 

And here's the code I'm actually currently using. For whatever that's worth. Any comments on how to improve it would certainly be appreciated. The 'zero' table could obviously be made 'growable'

from sage.symbolic.function_factory import function_factory

class Bessel:
    def __init__(self):
        self.JZ_max_m = -1
        self.JZ_max_n = -1
        self.TSIZE = 10

        def sJ_evalf(self, m, z, parent=None): return(bessel_J(m,z))
        def sJ_latex(self, m, z): return('\\mathbf{J}_{m}\\left(z\\right)')
        self.J = function_factory(name='Bessel_J',
            nargs=2, print_latex_func=sJ_latex, evalf_func=sJ_evalf)

    #def J(self, m, n): return( bessel_J(m,n) )
    def I(self, m, n): return( bessel_I(m,n) )

    # For now either we have the table or we don't. But in the future I
    # might like to be able to "extend" it, starting from what I've got.
    def JZ(self, m, n):
        if m > self.JZ_max_m or n > self.JZ_max_n:
            print('Creating new table for Bessel.JZ ...')
            self.JZ_table = []
            for mm in range(self.TSIZE):
                JZ_row = []
                def jn(z): return bessel_J(mm, z)
                low = 0; high = 1
                for nn in range(self.TSIZE):
                    root = -1
                    while root == -1:
                        try: root = find_root(lambda x:jn(x), low, high)
                        except (RuntimeError):
                            low = high
                            high = low+1
                            continue
                    #print('Found root: %s' %root)
                    low = root+1; high = low+1
                    #print('New interval: %s to %s' %(low,high))
                    JZ_row += [root,]
                self.JZ_table += [JZ_row,]
                self.JZ_max_m = self.TSIZE
                self.JZ_max_n = self.TSIZE
            print('Done')
        return(self.JZ_table[m][n])

def Bessel_Test():
    p1 = plot(lambda x:bessel_J(0, x), (x, 0, 32), linestyle='--')
    b = Bessel()
    p1 += plot(lambda x:b.J(0, x), (x, 0, 32), color='yellow')
    for r in range(10):
        p1 += point([b.JZ(0,r), 0])
    p1.show()

    p2 = plot(lambda x:bessel_J(9, x), (x, 0, 42), linestyle='--')
    p2 += plot(lambda x:b.J(9, x), (x, 0, 42), color='pink')
    for r in range(10):
        p2 += point([b.JZ(9,r), 0])
    p2.show()
link

posted Jan 26 '11

Mike Witt gravatar image Mike Witt
455 4 11 26
+1 for coming back and showing how it's done! I wish there were -- or wish I knew about! -- an equivalent Expression_factory. DSM (Jan 26 '11)

Your answer

Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
[hide preview]

Question tools

Tags:

Stats:

Asked: Jan 16 '11

Seen: 334 times

Last updated: Jan 26 '11

powered by ASKBOT version 0.7.22
Copyright Sage, 2010. Some rights reserved under creative commons license.