Python numerical integration with Simpson's rule

前端 未结 1 1227
闹比i
闹比i 2021-01-21 07:23

I have started to work through this book (Computational Physics Exercise 5.4) and its exercises and I got stuck with the following question:

Write a Python func

相关标签:
1条回答
  • 2021-01-21 08:02

    Your code is a little messy. You've defined a generator function float_range but you never use it, and the rest of your code is tacked onto that function, but should be separated from it, and not indented at the same level.

    You've also messed up the definition of the core function that needs to be integrated to get the Bessel function. You left out the constant m, and you mixed up the x and the t (theta). When you're evaluating the integral only the parameter t should vary - m and x are fixed.

    Anyway, here's some working code:

    from math import sin, cos, pi
    
    # The core function of the Bessel integral
    def f(m, x, t):
        return cos(m * t - x * sin(t))
    
    #The number of steps used in the Simpson's integral approximation
    N = 1000
    
    def J(m, x):
        ''' Approximate Bessel function Jm(x) for integer m '''
    
        # lower & upper limits of the integral
        a = 0.0
        b = pi
    
        # step size
        h = (b - a) / N
    
        # Sum the values for Simpson's integration
        s = f(m, x, a) + f(m, x, b)
        for i in range(1, N):
            t = a + i * h
            if i % 2 == 1:
                s += 4.0 * f(m, x, t)
            else:
                s += 2.0 * f(m, x, t)
    
        # multiply by h/3 to get the integral
        # and divide by pi to get the Bessel function.
        return s * h / (3.0 * pi) 
    
    for x in range(21):
        print(x, J(0, x), J(1, x), J(2, x))
    

    output

    0 1.0 3.59712259979e-17 5.16623780792e-17
    1 0.765197686558 0.440050585745 0.114903484932
    2 0.223890779141 0.576724807757 0.352834028616
    3 -0.260051954902 0.339058958526 0.486091260586
    4 -0.397149809864 -0.0660433280235 0.364128145852
    5 -0.177596771314 -0.327579137591 0.0465651162778
    6 0.150645257251 -0.276683858128 -0.24287320996
    7 0.30007927052 -0.00468282348235 -0.301417220086
    8 0.171650807138 0.234636346854 -0.112991720424
    9 -0.0903336111829 0.245311786573 0.144847341533
    10 -0.245935764451 0.0434727461689 0.254630313685
    11 -0.171190300407 -0.176785298957 0.139047518779
    12 0.0476893107968 -0.223447104491 -0.0849304948786
    13 0.206926102377 -0.0703180521218 -0.217744264242
    14 0.17107347611 0.133375154699 -0.152019882582
    15 -0.0142244728268 0.205104038614 0.0415716779753
    16 -0.174899073984 0.0903971756613 0.186198720941
    17 -0.169854252151 -0.0976684927578 0.158363841239
    18 -0.013355805722 -0.187994885488 -0.0075325148878
    19 0.14662943966 -0.105701431142 -0.157755906096
    20 0.167024664341 0.0668331241758 -0.160341351923
    

    The accuracy of this approximation is surprisingly good. Here are some values generated using the mpmath module, which supplies various Bessel functions.

    0 1.0 0.0 0.0
    1 0.76519768655796655145 0.44005058574493351596 0.11490348493190048047
    2 0.22389077914123566805 0.5767248077568733872 0.35283402861563771915
    3 -0.26005195490193343762 0.33905895852593645893 0.48609126058589107691
    4 -0.39714980986384737229 -0.066043328023549136143 0.36412814585207280421
    5 -0.17759677131433830435 -0.32757913759146522204 0.046565116277752215532
    6 0.15064525725099693166 -0.27668385812756560817 -0.24287320996018546772
    7 0.30007927051955559665 -0.0046828234823458326991 -0.30141722008594012028
    8 0.17165080713755390609 0.23463634685391462438 -0.11299172042407525
    9 -0.090333611182876134336 0.24531178657332527232 0.14484734153250397263
    10 -0.2459357644513483352 0.04347274616886143667 0.25463031368512062253
    11 -0.17119030040719608835 -0.17678529895672150114 0.13904751877870126996
    12 0.047689310796833536624 -0.22344710449062761237 -0.084930494878604805352
    13 0.206926102377067811 -0.070318052121778371157 -0.21774426424195679117
    14 0.17107347611045865906 0.13337515469879325311 -0.15201988258205962291
    15 -0.014224472826780773234 0.20510403861352276115 0.04157167797525047472
    16 -0.17489907398362918483 0.090397175661304186239 0.18619872094129220811
    17 -0.16985425215118354791 -0.097668492757780650236 0.15836384123850347142
    18 -0.013355805721984110885 -0.18799488548806959401 -0.0075325148878013995603
    19 0.14662943965965120426 -0.1057014311424092668 -0.15775590609569428497
    20 0.16702466434058315473 0.066833124175850045579 -0.16034135192299815017
    


    I'll let you figure out the plotting part of your exercise. :)


    Here's the mpmath code I used to generate those Bessel function values above, which are accurate to 20 significant figures:

    from mpmath import mp
    
    # set precision
    mp.dps = 20
    
    for x in range(21):
        print(x, mp.besselj(0, x), mp.besselj(1, x), mp.besselj(2, x))
    
    0 讨论(0)
提交回复
热议问题