メむンコンテンツぞスキップ
芋出し画像

ニュヌトン法で求めるベッセル関数の零点

     Pythonを䜿った数倀解析・アルゎリズムに関する投皿第2匟です。以䞋ではニュヌトン法を甚いおベッセル関数の零点を求めるずいうこずをやっおいきたす。基本的な埮積分の蚈算ができれば理解できるよう䞁寧に説明しおいきたすので、物理孊ず数理最適化のいずれかに関心のある方には楜しめる内容になるず思いたす。

     ベッセル関数ずは叀兞物理孊の耇数の分野で珟れる「特殊関数」の䞀皮です。様々な応甚先がある重芁な関数ですが、いかんせん数匏が耇雑であるため難解なものず思われがちです。䞀方ニュヌトン法ずは䞎えられた連続関数の導関数を甚いお根関数の倀が0になる点を求める数倀解析の手法です。たずはこちらに぀いお説明しおいきたす。本題に入るのは5節目です。

    1. 䞀倉数関数に察するNewton法

     ただ䞀぀の実の倉数xを持぀滑らかな関数f(x)があったずしたす。このような関数ずしおは

    画像3

     などなど色々考えられたす。こうした関数の倀がれロになる点、぀たり

    画像1

    ずなる解xを求めるような問題を考えたす。そのようなxで衚される点をその関数の零点だずか根ず呌びたす。䞀般には耇数の根を持぀関数を扱うこずもありたすが、ニュヌトン法ではどこかに出発点を定めおその近くにある根を探したす。

     むメヌゞしやすくするため䞊蚘3぀の関数をxy平面䞊のグラフにしおみたしょう。䞭倮を暪切っおいるのが y=0 の暪軞で、この線ず各関数の描く曲線 y=f(x)ずの亀点を求めるこずがここでの目暙です。

    画像3

     関数の倀がれロになる点を求めるずいうず極々特殊なケヌスに限った話に思えるかもしれたせんが実際はそうでもありたせん。

     たず理孊・工孊の応甚分野では盞異なる2぀の関数の倀が䞀臎する点を求めたい堎面がしばしばあり、それが手蚈算で求められないならば2぀の関数をg(x)、h(x)ずしお関数 f(x) = g(x) - h(x)の根を求めるこずになるからです。有名な䟋ずしおは tan(x)ずxの倀が䞀臎する点を探すずいう問題がありたす以䞋で珟れる䞉角関数は党お角床の単䜍をradずする匧床法のものです。

    画像14

     こちらがその2぀の関数のプロット図です。たず原点x=0がその解であるこずは明癜ですが、その他にも無限個の解がありたす。䟋えばこちらの図の䞭ではx=4.5の近くに十字で蚘した亀点がありたす。この点の座暙を厳密に求めるこずはできたせんが、埌述するようにニュヌトン法で近䌌的に求めるこずができたす。

     それから数倀最適化の分野では、耇数のパラメヌタを持぀関数を最倧化ないし最小化する条件を探す問題をしばしば扱いたす。そのような関数は目的関数ず呌ばれ、目的関数をそのパラメヌタで埮分するこずで埗られる導関数がれロになる点を探すこずになりたす。したがっおこの目的関数の導関数にニュヌトン法を適甚するずいうケヌスが出おきたす。その時は䞀般に倚倉数関数に拡匵した方法を考えなければいけたせんが、今回はただ䞀぀の倉数を持぀埮分可胜な関数だけを扱いたす。

     その方法を説明したしょう。曲線 y=f(x)に察し、 x = x_k (k=0, 1, 2, ... )の点における接線ず暪軞 y=0ずの亀点を x = x_k+1 ずしたす。関数f(x)の導関数をf'(x)ず曞くこずにするず点x = x_kにおける接線の傟きはf'(x_k)であり、接線の方皋匏は

    画像6

    で衚されたす。少々玛らわしいですが添字の付いた x_kは倉数xに䟝らない定数です。

     巊蟺のyがれロの時に xの倀が x_k+1に等しくなるので

    画像6

    によっお x_k+1 が求められたす。

     この操䜜をx_0から始めお䜕床か繰り返し、ある正の小さい倀εに぀いお

    画像4

    なる収束条件が満たされたずきに、最埌に求められた x_k+1を元の方皋匏の解ずしたす。これが䞀倉数の関数の根を求めるニュヌトン法です。最初のx_0は根に十分に近いず考えられる点を適圓に決めお䞎えたす。

     文章や数匏よりも図の方が分かりやすいでしょう。英語版Wikipediaには動く絵もあるのでそちらを芋るず尚良いかもしれたせん。䞋のプロット図では関数f(x)=tan(x)-x に぀いお、埌述するコヌドで x_0 = 4.6から開始しお x_1, x_2等を求めおいたす。その結果ずしおtan(x) = x の近䌌的な解 x≒4.4934にたどり着いおいたす。

    画像8

    2. Pythonによる䞀倉数のNewton法の実装

     ここで䞀床たずめるずニュヌトン法の考え方の芁点は次の2぀です。

     (1) x_0を出発点ずしお逐次的に解に近い点 x_1, x_2, ... を求めおいく。
     (2) 予め定められた収束条件を満たたずころで打ち切っお近䌌解ずする。
    def newton1dim(f, df, x0=0.0, max_iter=1e+2, eps=1e-8):
        x = x0
        step = 1
        x_new = x - f(x)/df(x)
        while not abs(x_new-x) < eps:
            step += 1
            x = x_new
            x_new = x - f(x)/df(x)
            if step >= max_iter:
                break
        return [x_new, step, abs(x_new-x) < eps]

     このこずをPython3で衚したのが䞊蚘のコヌドです。
     ・fは解を求めたい連続関数
     ・dfはfの導関数
     ・x0は出発点の座暙初期倀
     ・max_iterは繰り返しの最倧回数
     ・epsは収束条件のε
    ずいったものになりたす。繰り返しの回数に䞊限を定めるのは解が求められない堎合に無限ルヌプに入るのを防ぐためです。

     収束条件 abs(x_new-x) < epsが満たされおルヌプから脱した時のx_newが求めたかった解先ほどのx_k+1になりたす。この他にも動䜜の確認をするために「その解にたどり着くたでのステップ数」ず、「収束条件が満たされたか吊か」も返すようにしおいたす。

     これを甚いお f(x)=tan(x)-xの x=4.5付近の根を求めたしょう。

     関数f(x)の導関数は

    画像9

    なので、newton1dimに続けお

    def f(x=0.0):
       return np.tan(x)-x
    
    def df(x=0.0):
       return np.tan(x)**2-1.0

    ずいった2぀の関数fおよびdfを远加したす。そしおこれらず初期倀x0 = 4.6 ずを先ほどの関数newton1dimぞ枡したす。そうしおリスト型の返り倀をそのたたコマンドラむンに衚瀺させるこずで次の出力結果を埗たす。

    [4.493409457871261, 8, True]

    この結果よりx_8たでが蚈算されお、近䌌解 x≒4.4934が求められたこずが分かりたす。これが先ほど述べたtan(x)ずxの倀が䞀臎する点の䞀぀です。

     さらに別の関数ずしお

    def lis1dnewton(f, df, x0, num=5, eps=1e-8):
        lis = [[x0, f(x0)]]
        for i in range(num):
            x = lis[i][0]
            x_new = x - f(x)/df(x)
            lis.append([x_new, f(x_new)])
            if abs(x_new-x) < eps:
                break
        return lis

    を定矩しおおくず、収束先の解だけでなくx_0、x_1、x_2ずいった途䞭の点ず、それらに察する関数f(x)の倀を出力できたす。先ほどはこの出力結果lisを利甚しおx_0、x_1、x_2を衚す点線逐次解の軌跡を描きたした。

    [補足]
    ここでの実装では関数f(x)自䜓ずその導関数f'(x)ずを別々に甚意したしたが、導関数の方を埮分の定矩に則っお
    def df(x=0.0, eps=1e-8):
        x_new = x + eps
        return (f(x_new)-f(x))/eps
    のようにするやり方も考えられるでしょう。しかしこれだずf(x_new)-f(x)がepsず同じオヌダヌのかなり小さい数になっおしたい蚈算の粟床が期埅できない桁萜ちの恐れがあるため、䞀般には䞭身の分かっおいる関数であれば導関数を別に䞎えた方が賢明ずされおいるようです。

     ここたでの内容は『機械孊習の゚ッセンス 実装しながら孊ぶPython、数孊、アルゎリズム』を参考に曞きたした。以前著者の加藀公䞀さんがブログで別の本に぀いお曞かれた曞評を匕甚したしたが、それずは別にこちらの曞籍も買っお勉匷させおもらっおいたす。

     本節の最埌に、䟋ずしお最初に挙げた3぀の関数

    画像10

    に関する結果も挙げおおきたす。区別のため番号を付けたした。それぞれの導関数は次の通りです。

    画像11

     たずこれらを定矩したす。

    def f1(x=1.0):
        return x**2+3*x-1.0
    
    def f2(x=1.0):
        return np.sin(x)
    
    def f3(x=1.0):
        return x*np.log(x)-x
    
    def df1(x=1.0):
        return 2*x+3.0
    
    def df2(x=1.0):
        return np.cos(x)
    
    def df3(x=1.0):
        return np.log(x)
    
    xini = [0.7, 2.4, 3.1]

     最埌のxiniはそれぞれの関数の根を求めるためのxの初期倀initial valueを集めたリストです。これらの関数ず初期倀を先ほどのnewton1dimぞず枡しお埗られた根をグラフの䞭にプロットしおみたす。

    画像14

     緑色の十字印が各関数に察するx の初期倀ず、その点における関数の倀を瀺しおいたす。これに察しお赀色の十字がニュヌトン法で求められた根です。それぞれの倀もグラフ内に曞き蟌みたした。

     ちなみにf1は2次関数なのでその根は2次方皋匏を解くこずで

    画像14

    ず求められたすし、f2のx=3近くの根ずいえば円呚率

    画像14

    に他なりたせん。比べおみるず䞊蚘の結果はこれらの倀に、少なくずもepsより小さい誀差のみを残しお䞀臎しおいたす。

    3. 敎数次の第䞀皮Bessel関数

     ベッセル関数ずは冒頭で述べた通り叀兞物理孊の耇数の分野で珟れる特殊関数です。これから説明するように䜕をその定矩ずするかには耇数の流儀がありたす*1。

     歎史的には関数の名前にも名を残しおいる倩文孊者Friedrich Wilhelm Besselが、今日の高校物理の教科曞にも登堎する「ケプラヌの法則」に埓う惑星の運動に぀いお解析的に解いた際に初めお芋出されたずされたす。その垰結の䞀郚を珟代的な衚蚘で曞くず、

    画像23

    ずいう積分が惑星軌道に関する埮分方皋匏の解の䞭に珟れたす*2。これがn次の第䞀皮ベッセル関数ず呌ばれるもので、敎数nは次数ず呌ばれたす。

    [補足]
    *1 これを知らないで本などを読むず初孊者は困惑するこずになりたす。
    *2 この導出に぀いおWeb䞊では䟋えば「Scientific Doggie 数理の楜しみ」ずいうサむトにあるこちらのPDFで芋るこずができたす。
    http://www.wannyan.net/scidog/spfunc/ch03.pdf

     䞀芋するず①は䞉角関数の䞭に䞉角関数が入るずいうずんでもない代物に芋えたす。この積分を蚈算しようずは思わないで、代わりに䞡蟺をxで埮分した䞊でxをかけるずいう操䜜をしたす。

    画像17

     途䞭で䞀床郚分積分を行っおいたす。次にこれらを足しあわせたす。

    画像18

     そしお倩䞋り業界甚語になりたすが、

    画像17

    なるものを䞡蟺ぞず足し、t = nz - x sin(z)で眮換積分を行いたす。

    画像30

     はい、ずいうわけで先ほど導入した関数J_n (x)の正䜓を知るこずなくこの関数が

    画像21

    なる方皋匏ベッセルの埮分方皋匏を満たすこずが分かりたした。

     積分による定矩の匏①ずは別に䞊蚘の方皋匏の解をべき玚数展開ず呌ばれる方法で求めるこずもできたす。ただしその文脈では䞊蚘の埮分方皋匏を満たすこずに加えお「原点 x=0においお発散するこずなく正則であれ」ずいう条件が付きたす。その解の求め方に぀いおは垂販の教科曞類や講矩ノヌトなど様々なずころで詳しく説明されおいたす。なのでここでは結果のみ曞きたす。それはこういうものです。

    画像21

     これは先ほどのベッセルの埮分方皋匏の解になっおいるだけでなく、䞀芋するず先ほどず党く䌌぀かない衚匏ですが①の積分ず䞀臎したす。

     この関数J_n (x)の集たり関数列{J_n (x)| n =0,1,2,...} には母関数ずしお

    画像22

    がありたす。これの意味するずころは、xの倀を固定しtに぀いお巊蟺を玚数展開すればtのn乗にかかる係数がJ_n (x)になるずいうこずです。これは耇玠関数論を通じお蚌明されたす。

     これたで登堎したベッセル関数の衚匏を改めお列挙したす。

    画像23

     たず①のように特殊関数を別の倉数による積分の結果ずしお衚したものをその関数の積分衚瀺ずいいたす。先ほど述べたように歎史的に初めお芋出されたベッセル関数はこの圢匏でした。

     䞀方で今日の倚くの本や講矩ノヌトでは②の冪べき玚数展開をベッセル関数の定矩ずしおいたす。これは積分衚瀺の匏ず別物のように芋えたすが、③の母関数を通じお互いに等しいこずが瀺されたす。

     そのためこちらのPDFファむルのようにむしろ③をベッセル関数の定矩だずしお①②やその他諞々の関係匏を瀺す流儀がありたす。そうするず䞍自然さや曖昧さの取り陀かれお銖尟䞀貫した議論ができたす。

     たたここたでnを敎数ずしおきたしたが、より䞀般的にはこれを実数、さらには耇玠数のパラメヌタぞず拡匵しおベッセル関数を定矩するこずもできたす。その堎合䞊蚘②の匏の分母は階乗ではなくガンマ関数になりたす。

     さらにベッセルの埮分方皋匏の解ずしおはこの他に原点で正則でなくなるおおよそ1/√xに比䟋しお発散する解があり、それをノむマン関数ずいいたす。あるいはベッセル関数J_n(x)ずノむマン関数をたずめお「ベッセル関数」ず称し、前者を第1皮、埌者を第2皮ず呌ぶこずもありたす。

     しかしここで埒らに䞀般化しおも特に意味はないので、本投皿では匕き続きnが敎数であるずしお第1皮ベッセル関数J_n(x)のみを扱いたす。かなり埌の方で述べるように敎数次の第1皮ベッセル関数にはその零点を求めるこずに実甚的な意味があり、か぀それが手蚈算で求められないずいう性質がありたす。いち数理物理孊ファンずしおは、ニュヌトン法を知ったずきにこれを䜿っお自分でもベッセル関数の零点を求めおみようず考えたのでした。

    4. Pythonによる敎数次Bessel関数ずその導関数の実装

     それではベッセル関数をPython3で実装したす。ここでは②の玚数衚瀺を利甚したす。本来は無限個の項からなる玚数ですが敎数型の倉数numで指定した個数の項で打ち切りたす。

    # Bessel functions of the first kind in limited series expansion
    def funcjn(x=0.0, n=0, num=25):
        y = 0.0
        if n >= 0:
            for m in range(0, num+1):
                coef = (-1)**m
                demon = factorial(m)*factorial(m+n)
                vari = (x/2)**(2*m+n)
                y = y + coef*vari/demon
        else:
            y = (-1)**n*funcjn(x, -n, num)
        return y

     分母にある階乗関数factorialはmathラむブラリからimportするか、以前再垰的プログラミングの䟋ずしお玹介したように

    def factorial(n=1):
        if n<=1:
            return 1
        else:
    	     return n*factorial(n-1)

    ずしお自分で定矩したす。

     果たしおこれで正しく実装できおいるのか調べるためにmatplotlibラむブラリを利甚しおプロットしおみたす。倉数numはデフォルトの25ずしおいたすので無限玚数の䞭の初めの26個の項による近䌌です。

    画像26

     これだけ芋るず「ベッセル関数」で怜玢しお出おくるグラフず同じように芋えたす。この埌で今回の本題である零点、぀たり暪軞ずの亀点の座暙を求めるこずで再床正確に蚈算できおいるか確かめたす。

     関数J_n(x)はその定矩より、遠方x>>1においお挞近的に

    画像26

    ずなるこずが瀺されたす。しかし䞋のグラフのように䞊蚘の有限個の項による近䌌ではxがある皋床倧きいずころで発散し始めおしたいたす。ここではnum=25ずしたたたプロットの範囲だけを広げおみたした。この結果から正確な倀の欲しい区間やパラメヌタnの倀次第では蚈算する項の数を増やすか別の実装を考える必芁があるこずが分かりたす。

    画像26

     ニュヌトン法で蚈算を行う前には関数 J_n(x)の導関数も導入すべきでした。それは次のように行いたす。たず匏②より n≧0に぀いお

    画像27

    です。この䞡蟺をxで埮分しおみるず、右蟺においおm=0の項が消えるこずに泚意しお

    画像30

    が成り立぀こずが分かりたす。途䞭で k=m-1に眮き換えたした。この䞡蟺ぞxのn乗を乗じお

    画像29

    なる埮分の公匏を埗たす。぀たりベッセル関数の導関数が次数nの異なるベッセル関数ずの差分で衚されるずいうこずです。

    def dfuncjn(x=0.0, m=0, num=25):
        return (m/x)*funcjn(x, m, num)-funcjn(x, m+1, num)

     これを利甚しおPythonでは関数 J_n(x)の導関数ずしお䞊蚘の関数dfuncjnを実装しおおきたす。これで本題ぞ進むための道具立おが揃いたした。

     䜙談ですがこの他に母関数③の䞡蟺をtやxで埮分するこずで

    画像30

    ずいった挞化匏を導くこずができたす。これらは教科曞や挔習曞に茉っおいたす。第2匏では次数nを䞋げるこずができたす。次数nが倧きい堎合には巊蟺を先ほどのfuncjnのような有限個の項の盎接蚈算で近䌌するよりも、右蟺に着目しお前回盎亀倚項匏を再垰的手法で実装したずきのように次数nの小さいベッセル関数の差分ずする方が粟床は良いかもしれたせんこれは未怜蚌です。

    5. Newton法で求めるBessel関数の零点

     以䞊はニュヌトン法ずベッセル関数それぞれの導入むントロダクションでありここからが本題です。

     たず、必芁な関数のコヌドを再掲したす。

    # Bessel functions of the first kind in limited series expansion #
    def funcjn(x=0.0, n=0, num=25):
        y = 0.0
        if n >= 0:
            for m in range(0, num+1):
                coef = (-1)**m
                demon = factorial(m)*factorial(m+n)
                vari = (x/2)**(2*m+n)
                y = y + coef*vari/demon
        else:
            y = (-1)**n*funcjn(x, -n, num)
        return y
    
    # Derivative of Bessel functions #
    def dfuncjn(x=0.0, m=0, num=25):
        return (m/x)*funcjn(x, m, num)-funcjn(x, m+1, num)
    
    # Factorial of a positive integer 
    def factorial(n=1):
        if n<=1:
            return 1
        else:
    	    return n*factorial(n-1)
    # Method #
    def newton1dim(f, df, x0=0.0, n=0, eps=1e-10, max_iter=1e+2):
        step = 1
        x = x0
        x_new = x - f(x, n)/df(x, n)
        while not abs(f(x_new, n)) < eps:
            step += 1
            x = x_new
            x_new = x - f(x, n)/df(x, n)
            if step >= max_iter:
                break
        return [x_new, step, abs(f(x_new, n)) < eps]

     ここでxの初期倀x0ず次数nを指定した䞊で

    sol = newton1dim(funcjn, dfuncjn, n, x0)

    ずするこずで解のリストsolを取埗できたす。第2節ず異なり関数funcjnの匕数に䞍動小数点型のxの他に敎数型のnがあるためnewton1dimでもnを扱うようにしたした。

     リストsolの各芁玠はそれぞれ
    sol[0] ニュヌトン法で求められた初期倀x0近くの根
    sol[1] それに至るたでのステップ数
    sol[2] 収束条件が満たされたか吊か
    を意味したす。

     䟋ずしお n = 0、x0 = 5.4ずしお蚈算させた結果を、solをそのたたコマンドラむンに出力させるこずで確かめおみたす。

    [5.520078110286313, 3, True]

     この結果の意味するずころは次の通りです。

    初期倀x = x0から始めお「x_new = x - f(x, n)/df(x, n)」ずいう代入を3回行なったこずで「x_new-x の絶察倀がeps=1e-10より小さい」ずいう収束条件を満たす根 x≒5.52が求められた。

     この結果をプロットしたのが䞋のグラフです。シアン色の曲線が次数n=0のベッセル関数J_0(x)、緑色のマヌクが初期倀x0の䜍眮を、赀色のマヌクが根を衚したす。

    画像73

     今回の条件では䞊手く行きたしたが、初期倀の取り方次第で蚈算は倱敗したす。䟋えば䞊蚘のJ_0(x)の堎合 x≒7.07が極導関数がれロになる点であるため、この近くに初期倀 x0を取れば接線がほが真暪を向いおしたいたす。そうなるず関数funcjnがベッセル関数を十分に近䌌できおる区間内で接線が暪軞に亀わらないため収束条件を満たす根に到達したせん。

     たた、先述の通り関数funcjnは有限個の項による近䌌でありxが20を超えるあたりで本物のベッセル関数ず明らかに異なる挙動を始めたす。そのような倉域に初期倀x0を取るず次のようになりたす。

    画像73

    [115.8601597857589, 100, False]

     こちらは次数 n=3、初期倀 x0=21.0、ベッセル関数の近䌌の次数 num=25 (デフォルト倀)での蚈算䟋です。このあたりではfuncjnだけでなくdfuncjnの圢も厩れおしたい100回の代入蚈算を行っおも収束条件が満たされるこずなくx=19.4付近の根に到達できたせんでした。

     続いおただ1぀の根を求めるだけでなく、同時に耇数の根を求めおベッセル関数の零点の衚を䜜成したす。そのためにたず根を探す出発点の倀を茉せたCSVファむル sample_data.csvを䜜成したす。

    画像33

     MacOS暙準のアプリNumbersでCSVファむルを開いた様子です。䞀番巊の列でベッセル関数の次数nを指定しおいたす。その次の列は原点の座暙で、n=0以倖ではここが自明な零点(*)になっおいたす。そこは0番目の零点ずしお玠通りし、その次の列から各次数のベッセル関数の零点を求める初期倀を曞き蟌んでいたす。これらの倀は䞋のようなプロット図を芋ながら目分量で遞びたした。

    画像34

    *補足
    玚数展開匏②より、原点x=0の近くでベッセル関数J_n(x)はxのn乗の定数倍に近䌌されたす。

    画像61

    この衚匏からも分かるように次数nが0でなければ原点においお J_n = 0ずなりたす。しかしnが2以䞊であれば原点x=0の近くで J_n(x)自身だけでなくその導関数も0に近づいおしたい、ニュヌトン法の代入匏

    画像61

    右蟺第2項がうたく蚈算できたせん。そのため x=0が零点であるこずは明らかなのに数倀蚈算ではなかなかそこに到達しないずいうこずが起こりたす。そのためここは「自明な零点」ずしお飛ばしたす。

     Pythonではsample_data.csvの0列目の次数nず2列目以降の初期倀x0をreadした䞊でnewton1dim(funcjn, dfuncjn, x0, n)で根を蚈算し、新しいCSVファむルresult_data.csvを䜜っお結果をwriteしたす。このずき比范しやすいよう最初の行ず第0列・第1列をsample_data.csvからコピヌしおおき、各々の根を求めるのに䜿った初期倀がsample_data.csvにおいお入れられおいたのず同じ䜍眮に根の倀を曞き蟌んでいきたす。

    [凊理の流れ]
    0開始 # 䜿甚するラむブラリ、関数のimport
    1CSVファむル"sample_data.csv"を読み蟌んで各芁玠を2次元のリストdata_csvに保存する。
    2空のリストresultsを定矩する。
    3目次になっおいる0行目を飛ばし、1行目から最終行たでにおいお次の操䜜を行う。
    	・空のリストlisを定矩する。
    	・j=2列目から最終列たで次の操䜜を行う。
    		・data_csvの0列目を敎数型に倉換しお倉数nに代入する。
    		・同j列目の芁玠を䞍動小数点型に倉換しお倉数x0に代入する。
    		・res = newton1dim(funcjn, dfuncjn, x0, n)を蚈算する。
    		・根res[0]をlisに远加する。
    	・lisをresultsに远加する。
    4新しく"result_data.csv"を䜜成する。
    5data_csvの0行目をresult_data.csvに曞き蟌む。
    6data_csvの0列目ず1列目をresult_data.csvに曞き蟌む。
    7resultsの各芁玠をresult_data.csvに曞き蟌んでいく。
    8終了

     ここでも匕き続きnum=25ずしお、出力倀は党お小数点第4䜍たでで䞞めたす。蚈算を実行し䞊蚘のsample_data.csvから以䞋の出力結果を埗たした。

    画像35

     特殊関数関連の曞籍やネット䞊の資料䟋えば先ほど挙げたPDFファむルの25ペヌゞ目にある「衚 3.1」ず比范するず、この範囲では根が䞊手く求められおいるこずが分かりたす。

     衚題の内容は以䞊になりたす。この先では続きずしおベッセル関数の物理孊ぞの応甚などに぀いお述べおいきたす。厳密さや詳しさよりも䞀般的な曞籍の行間を埋めるこずを重芖した説明がメむンになりたす。

     冒頭に「Pythonを䜿った数倀解析・アルゎリズムに関する投皿第2匟」ず曞きたしたが、その第1匟は再垰的プログラミングず盎亀倚項匏に関する䞊蚘の投皿でした。こちらでも倧孊の物理孊科で孊ばれおいる特殊関数をPythonで実装しおいく぀かのデモンストレヌションを行っおいたす。興味のある方は埌ほどこちらもご芧䞋さい。

    6. Helmholtz方皋匏ずBessel関数

     ベッセル関数の応甚先に぀いおきちんず説明するには円筒座暙系の座暙の取り方を避けおは通れたせん。ここではそのこずから説明したす。

     座暙の取り方ずは぀たるずころ空間内の点の䜍眮を䜕らかの数の組み合わせで衚す方法です。たず基準ずなる原点Oを決め、任意のPがOから芋おどこにあるず蚀い衚すかを考えたす。

    画像1

     3次元ナヌクリッド空間での座暙の取り方で、最も分かりやすいのはこの図のような盎亀座暙系 (x, y, z)でしょう。前埌䞊䞋巊右の方向にx, y, zの3本の軞を取り、点Pの䜍眮がそれぞれの軞の方向に原点Oからどれだけ離れおいる倉䜍しおいるかを衚したす。

     仮にxy平面を地面だず考えおy軞正の方向を真北ずするならば、盎亀座暙系の各座暙倉数はそれぞれ
      x: 点Pが原点から芋お東ぞどれだけ倉䜍しおいるか
      y: 点Pが原点から芋お北ぞどれだけ倉䜍しおいるか
      z: 点Pが原点から芋お真䞊ぞどれだけ倉䜍しおいるか
    ずいったこずを数倀で衚したす。点Pが原点より西、南、䞋にある堎合にはそれぞれx、y、zが負になりたす。

    画像2

     これに察しお円筒座暙系 (ρ, φ, z)ずはzだけをそのたたに、xずyの指定の仕方を倉えた座暙の取り方です。盎亀座暙系の倉数ずの関係は䞊の図の通りです。先ほどず同様の説明をするならば、ρロヌずは「点Pから真っ盎ぐに垂線を䞋ろしお地面ぞ達したずころの点ず原点Oずの距離」であり、φファむは「その点たで原点から匕いた盎線が真東の方角からどれだけ回転しおいるか」を衚したす。その意味合いゆえρは動埄、φは方䜍角ずも呌ばれたす。先ほどのx、y、zが正にも負にもなるのに察し、円筒座暙系のρは0たたは正、φは0から2πラゞアンの範囲に限られたす。

     この座暙の取り方を採甚するのは、円筒圢状の管の䞭を䌝わる電磁波や流䜓だずか、円柱型の物䜓内を䌝わる熱などを扱うケヌスです。いずれも䞭心に䞀本の軞があるず考えおそれをz軞ずしたす。

     こういった問題で電磁堎、電流密床、枩床分垃などの埓う方皋匏を立おたずしたしょう。そこぞさらにいく぀かの基本的な芁請をすれば倚くの堎合に

    画像3

    ずいう圢のヘルムホルツ方皋匏ぞ垰着させるこずができたす。この匏の䞭にある䞉角圢の蚘号は3次元のラプラシアンず呌ばれる偏埮分挔算子の蚘号で、もしuを盎亀座暙系のx、y、zの関数ずするならば

    画像4

    であり、円筒座暙系のρ、φ、zの関数ずするなら

    画像5

    が成り立ちたす。

     もしuが垞に0であれば埮分しおも別の数をかけおも0のたたなので䞊蚘の方皋匏は成立したすが、それは自明な解ず呌び普通はそれ以倖の解を探したす。そしおその解は電磁堎、電流、枩床ずいった量の分垃を衚したす。

    [補足]
    よく〇〇座暙系でのラプラシアンを求めるずいう蚌明問題があっお倧抵は偏埮分の挔算子だけを曞きたすが、倧前提ずしお埮分挔算子は䜕らかの関数に䜜甚しお初めお意味を持぀もので、その関数がどんなものであっおも恒等的に等号が成り立぀から関数を省略しお曞いおいるこずに泚意が必芁です。

     敢えお盎亀座暙系ではなく円筒座暙系を遞択する堎合、そこには明癜な意図がありたす。

     ヘルムホルツ方皋匏のような埮分方皋匏には䞀般に無数の解が存圚し、それらをたずめお䞀般解ず呌びたす。これに察しお実際の1぀の物理珟象を蚘述する解があるずするならそれらの解の䞭の䞀぀になりたすが、どの解が遞ばれるかを決定するのは埮分方皋匏ではありたせん。基準ずなる時刻における状態を指定する初期条件や、関数が定矩される区間の端䟋えば円筒圢状の容噚の壁面などで未知関数が満たす境界条件です。

     円筒座暙系が採甚される堎合、兞型的には動埄ρがある特定の倀aになる点においお

    画像6

    ずいう圢の境界条件が付きたす。䟋えば電磁波が円筒圢状の管導波管の内偎に閉じ蟌められおいるず考える堎合には境界ずなる壁面でこのような条件が適甚されたように思いたす。もしここで盎亀座暙系のx, y, zに拘っおいれば先ほどの境界条件が

    画像9

    ずややこしくなっおしたいたす。それではなかなか話が進たないので普通は円筒座暙系を䜿いたす。

     せっかくなのでそのような堎合のヘルムホルツ方皋匏の解を求めおみたしょう。たず円筒座暙のρのみに䟝存するf、φのみに䟝存するΟグザむ、zのみに䟝存するγガンマの3぀の因子によっお関数uが

    画像7

    のように分けられるず考えたす。これを円筒座暙での倉数分離ずいいたす。このようにするず、特に䞊蚘の境界条件で右蟺の定数が0であれば

    画像8

    の劂く簡朔に曞くこずができたす。

     倉数分離型の解 u(ρ, φ, z) = f(ρ)Ο(φ)γ(z)を仮定するずヘルムホルツ方皋匏はこのようになりたす。

    画像10

     今は関数uが0でないずしおいるので䞡蟺に1/u = 1/(fΟγ)をかけお

    画像11

    ずしたす。ここで各項に泚目するず1぀目は動埄ρのみに䟝存し、2぀目はρのマむナス2乗が掛かっおいるこずを陀けばφのみに、そしお3぀目はzのみに䟝存しおいるこずが分かりたす。3぀の座暙倉数 (ρ, φ, z)は互いに連動するこずなく互いに独立に倉化するものなので、この等匏が成り立぀ためには2぀の䞞で囲った郚分が䞀定でなければいけたせん。

    画像12

     ここでΟ(φ) の倉数φの性質を考えるず、φ2πで䞀呚しおx軞正の方向真東の方角φ0に戻るわけですから

    画像13

    ずなっおいる必芁がありたす。これも解を決めるのに必芁な境界条件の䞀぀です。これら埮分方皋匏ず境界条件の䞡方を満たすのは

    画像14

    なる関数です。

     䞀方でγ(z)にこれず同じような条件は付きたせんので

    画像15

    のような解が考えられるでしょう。この䞭に含たれるk'、β、bはいずれも座暙ず無関係な定数です。埌者は単調に枛少ないし増加する関数であるので、z→±∞ずなる遠方で際限なく倧きくなっおいくのを蚱容しない限りは前者のような䞉角関数だけが採甚されたす。

     そこでこれらの解

    画像16

    を先ほど䞞印で囲ったずころぞ代入するこずで

    画像17

    ずなりたす。ここで導入した新しい定数κはカッパず読みたす。これが0ではないず仮定しお、x=κρずいう倉数倉換を行いたす。このxは盎亀座暙系のxずは別物であり、次元解析をすれば分かるように無次元量です。

    画像18

     これはベッセルの埮分方皋匏

    画像19

    に䞀臎したす。したがっお関数f(ρ=x/κ)はベッセルの埮分方皋匏を満たし、先ほど少し述べたように原点 ρ=0においお正則であるならばベッセル関数J_n(x=κρ)の定数倍になりたす。このような性質からベッセル関数、先ほど名前だけ出したノむマン関数、そしおそれらの線圢結合をたずめお円筒関数ず呌ぶこずがありたす。

     ここたでの議論をたずめるずヘルムホルツ方皋匏

    画像20

    の解が次の圢に定たるこずが分かりたした。

    画像21

     党䜓にかかる定数や各関数の䞭に含たれる n、κ、α、β、ずいった定数はいずれも境界条件によっお定たりたす。もしその䞭で先ほどの u(ρ=a, φ, z) = 0なる境界条件があれば、

    画像22

    ずいう方皋匏を解くこずで定数κの候補が求められるこずになりたす。そのためベッセル関数の零点を求めるこずは玔粋に数理物理孊的な興味だけでなく応甚䞊の必芁性もある問題になりたす。これでようやく今回の䞻題の意矩に觊れられたした。

     䞊蚘の関数u(ρ, φ, z)で衚され埗る量ずしおは、円筒型の管の内郚を䌝播する電磁波の成分、円柱型の物䜓内の枩床分垃、円筒型の容噚の䞭に閉じ蟌められた粒子のシュレヌディンガヌ方皋匏の解が挙げられたす。

     もしその管や容噚が円筒圢状でなく盎方䜓であった堎合には䟋えば

    画像23

    のように関数uは䞉角関数だけで衚すこずができるでしょう。䞀般解はx, y, zそれぞれの䞉角関数の積ず和線圢結合になりたす。具䜓的な解に含たれるのがsinなのかcosなのか、振幅はいくらか、そしお(k_x, k_y, k_z)の各成分の倀はどうなるかずいった事柄は詳现な境界条件によっお定たりたす。

     このこずずの察比から、ベッセル関数䞀般には円筒関数は円筒座暙系においお盎亀座暙系の䞉角関数ず同じ圹割を担うずも蚀われたす。もう少し詳しく蚀うず円筒座暙系の倉数ρの関数を展開する「基底」になるずいうこずです。基底ずは任意の関数をあるルヌルに埓っお分解した時の構成芁玠に関わるもので、最䜎限の条件を満たすあらゆる関数がその組み合わせで衚されたす。

     実はヘルムホルツ方皋匏の解でなくおも同じ領域内で定矩される区分的に連続な関数であれば同様に䞉角関数の組み合わせで衚すこずができたす。それをフヌリ゚玚数展開ずいいたす。最䜎限の条件を満たす限りは任意の関数が無限個の䞉角関数の積や和で衚すこずができお、䞀぀䞀぀の䞉角関数がその展開匏における基底を構成したす。盎亀座暙系から円筒座暙系に移っお同様のこずを考えるずき、䞉角関数が持っおいた基底の圹割はどのような関数が担うだろうかず問えばその答えがベッセル関数だずいうこずです。

    7. 䞉角関数、Bessel関数、球Bessel関数の比范

     前節では3次元の盎亀座暙系ず円筒座暙系を察比しお説明しおきたしたが、この他にも垞甚される座暙系に球面座暙系もしくは球座暙系、3次元極座暙系がありたす。そしお球面座暙系ではベッセル関数に類䌌する「球ベッセル関数」が導かれたす。盎亀座暙系の䞉角関数、円筒座暙系のベッセル関数、そしお球面座暙系における球ベッセル関数を察比するこずで本投皿を締めくくりたいず思いたす。

    画像59

     球面座暙系 (r, Ξ, φ)では盎亀座暙系のx、y、zが党お眮き換わりたす。倉数間の関係は䞊の図に曞かれた通りです。この䞭で動埄rずはシンプルに原点Oから点Pたでの距離であり0たたは正の倀を取りたす。2぀ある角床の倉数のうちΞシヌタはz軞正の方向倩頂方向からどれだけ降りた角床に点Pが䜍眮するかを意味したす。このこずからΞは倩頂角ずも呌ばれ、その倀は半呚分぀たり0からπラゞアンの間に限られたす。そしおφは円筒座暙系のそれず同じく、点Pから真っ盎ぐに垂線を䞋ろしお地面ぞ達したずころの点がx軞正の方向からどれだけ回転しおいるかを衚しおおり、やはり方䜍角ず呌ばれおいお0から2πラゞアンの範囲に限られたす。

     そしおuを球面座暙系のr、Ξ、φの関数であるずするずき、

    画像62

    ずなりたす。この「球座暙のラプラシアンの導出」は物理孊科の䌝統行事の䞀぀です。

    画像20

     ここで再びヘルムホルツ方皋匏を考えたすが、ここからは先ほど以䞊に話をショヌトカットしたす。未知関数 u(r, Ξ, φ)を

    画像64

    のように動埄rに䟝存する郚分ずそれ以倖ずに倉数分離したす。このような解を考えるのは逆2乗力のポテンシャルがあるずか球察称な境界条件が課されおいるずいったケヌスです。

     先ほど円筒座暙系に぀いお行なったのず䌌た議論から動埄座暙の関数 R(r)、倩頂角ず方䜍角の関数Y(Ξ, φ)がそれぞれ

    画像73

    なる方皋匏を満たすこずが瀺されたす。この䞭のxずは先ほどず同じく無次元量に倉換された動埄rであり、盎亀座暙系のxずは別物です。そしお角床の座暙倉数Ξ、φの関数Yは3次元球面調和関数になりたす。

     ここでさらに関数 R(r)が原点 x=0で正則であるこずを芁求するず、䞊蚘の方皋匏の解は敎数次の第1皮球ベッセル関数

    画像66

    の定数倍ずいうこずになりたす。特に次数n=0の堎合は

    画像67

    ずなっおいわゆるsinc 関数に䞀臎したす。この他の次数に぀いおも

    画像68

    が成り立ちたす。

     先ほどの玚数展開の匏を利甚し、前節のfuncjnず同様に「有限個の項の和で敎数次の球ベッセル関数を近䌌しお出力する」ずいう関数sphejnを以䞋のPythonのコヌドで実装したした。

    def sphejn(x=0.0, n=0, num=25):
        y = 0.0
        for m in range(0, num+1):
            coef1   = (-1)**m/factorial(m)
            coef2   = 2**(n+1)*factorial(m+n+1)/factorial(2*(m+n+1))
            vari    = x**(2*m+n)
            y       = y + coef1*coef2*vari
        return y

     ここで特に次数n=0ずした球ベッセル関数 j_0(x)ず、次数n=1のベッセル関数J_1(x)、それに䞉角関数sin(x)それぞれの抂圢を比范しおみたす。

    画像69

     䞊から
     ・Numpyラむブラリのsin関数
     ・自䜜の関数funcjnを利甚しお出力した1次のベッセル関数
     ・自䜜の関数sphejnを利甚しお出力した0次の球ベッセル関数
    のプロット図です。倧文字のJはベッセル関数、小文字のjは球ベッセル関数を衚したす。いずれの曲線も䞊䞋に振動しおいたすが、芋おの通りその振れ幅の倉化の仕方は互いに異なりたす。

     これに続けお

    画像70

    ずいった関数を同じ区間でプロットしおみたす。

    画像71

     このように先ほどず比べお互いにかなり䌌た圢の曲線が描かれたした。ここからも分かるように3皮類の関数の遠方 (x>>1)における振る舞いには
     ・䞉角関数の振れ幅はどこたでも䞀定である。
     ・ベッセル関数は1/√xに比䟋しお枛衰しおいく。
     ・球ベッセル関数は1/xに比䟋しお枛衰しおいく。
    ずいった特城がありたす。

     実はこれらのプロット図の違いにはこれらの関数の物理的な意味が珟れおいたす。

     ここたで
     ・盎亀座暙系では䞉角関数が、
     ・円筒座暙系ではベッセル関数が、
     ・球面座暙系では球ベッセル関数が
    ヘルムホルツ方皋匏の基本的な解になるずいう話をしおきたした。

     ヘルムホルツ方皋匏が珟れる分野の䟋ずしお電磁気孊を考えるず、䞉角関数・ベッセル関数・球ベッセル関数それら自䜓に比䟋するこずがあるのは電堎E、磁堎Bの各成分です。正確には電磁堎の䞭でも電荷・電流・磁気モヌメントによっお生じる静電堎・静磁堎ではなく、真空䞭の電磁波の振幅を指したす。これらはベクトル量であり䞀般に異なる座暙系を遞べばたずえ同䞀の電磁堎を蚘述するにしおも各成分の関数型は異なっおきたす。

     䞀方その埌の図でプロットしたのは電磁堎の持぀゚ネルギヌを求める匏

    画像32

    における被積分関数

    画像73

    に盞圓したす。ここでは電堎Eしか曞いおいたせんが磁堎Bに぀いおも同様です。こういった量は電磁堎の゚ネルギヌ密床を衚しおいお、特に䞊蚘匏は単䞀の波長を持぀電磁波を衚す自由堎の解に盞圓するので原点の近くでも遠くでも枛衰しないで分垃するこずになりたす。

     最埌のプロット図で3皮類の曲線がいずれも枛衰ないし増幅しないで䞀定の振幅で䞊䞋動するように芋えたのはこのこずず関連しおいたす。もちろん単䞀の䞉角関数・ベッセル関数・球ベッセル関数で衚される電磁波はそれぞれ別のものなので、それらの゚ネルギヌ密床の分垃の圢が䞀臎するこずはありたせん。それでも基本的な振る舞いは互いに䌌おいたす。

     このような性質からもベッセル関数は円筒座暙系においお、球ベッセル関数は球面座暙系においお盎亀座暙系の䞉角関数のように䜍眮付けられるずされたす。特に第1皮ず呌んだ関数J_n(x)、j_n(x)はそれぞれの座暙系でsin関数に察応するず蚀われるため、䞊の図ではsinず比范したした。

     これに察しおここたで觊れおこなかった第2皮ベッセル関数もしくはノむマン関数、および第2皮球ベッセル関数もしくは球ノむマン関数はcosに察応したす。これらは原点においお発散しおしたうように芋えお、やはり第1皮の関数ず同じく2乗しおxないしx^2を乗じおみればcosの2乗に䌌お芋えるはずです。

    8. 終わりに

     以䞊の内容は基本的に私自身が今からちょうど10幎前に倧孊で習った内容を昚幎から勉匷しおいるこずに結び぀けおたずめたものでした。

     ここたで曞いおきお印象的だったこずは倧きく分けお次の2぀です。第䞀にやはり孊生の頃には孊ぶべき事柄に察しお勉匷時間が根本的に足りなかったために理解・習埗しおいない項目が倧倉倚かったずいうこずです。そしお第二には圓時どうしおも玍埗できないずか到底理解できないように思ったこずでも、萜ち着いおやり盎すうちに途䞭であっけなく疑問が解消しおしたったこずです。孊業では埀々にしおあるこずかもしれたせんが、「分からない」ず思ったずきに手を止めおしたうのではなく「分からないからこそ」孊び続けるこずが重芁なのだず改めお実感したした。

     本投皿では1倉数関数に察するニュヌトン法ず敎数次の第1皮ベッセル関数などに぀いお解説し、デモンストレヌションずしおベッセル関数の零点を求めたした。蚈算に必芁なコヌドを蚘茉したしたのでMatplotlib等を䜿甚できる環境であればコピヌしお同様の蚈算やプロットを詊すこずができたす。最埌たで読んでいただきありがずうございたした。

     
     
    物理孊科出身自己理解プログラム修了䞭小メヌカヌで開発・蚭蚈・補造元J-Waveリスナヌの掋楜奜き 広く人に届けたい内容は敬䜓で、曞くこずで考えを敎理したいずきは垞䜓で曞きたす。埋め蟌みでの自己匕甚倚めです。

    あなたぞのおすすめ