Juliaによる積分公式の検算
Julia Advent Calendar 2023 3日目です🎄
はじめに
時間に依存しないSchrödinger方程式に変分法を適用する, すなわちエネルギーを波動関数の汎関数
環境
versioninfo()
Julia Version 1.8.3
Commit 0434deb161 (2022-11-14 20:14 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.1 (ORCJIT, tigerlake)
Threads: 1 on 8 virtual cores
パッケージ
ガウス積分の積分領域には無限大が含まれるため, 数値積分のパッケージでは100とか1000とか適当な大きな数を入れて有限区間を指定することになる. しかし, QuadGK.jlでは積分領域にInf
や-Inf
を使える(いい感じに処理してくれる)ことから, このノートでは全面的にQuadGK.jlを採用した. なお, 多変数の場合はHCubature.jlやMonteCarloIntegration.jlの方が有利になるため, これらのテストも兼ねて3つのパッケージの比較も行う. また, 公式の実装にSpecialFunctions.jlとGSL.jlを使用する. 初めての場合は using Pkg; Pkg.add("パッケージ名")
を実行してインストールを行う.
using Pkg
Pkg.add("QuadGK")
Pkg.add("HCubature")
Pkg.add("MonteCarloIntegration")
Pkg.add("SpecialFunctions")
Pkg.add("GSL")
使用前は毎回 using パッケージ名
を実行してパッケージを読み込む.
using Printf
using QuadGK
using HCubature
using MonteCarloIntegration
using SpecialFunctions
using GSL
まずは簡単な積分を題材としてQuadGK.jl, HCubature.jl, MonteCarloIntegration.jlのそれぞれの使用例を比較する.
I₁ = quadgk(x -> x^3, 0, 2)[1] # QuadGK.jl
I₂ = hcubature(x -> x[1]^3, [0], [2])[1] # HCubature.jl
I₃ = vegas(x -> x[1]^3, [0], [2]).integral_estimate # MonteCarloIntegration.jl
@show I₁
@show I₂
@show I₃
# output
I₁ = 4.0
I₂ = 3.999999999999999
I₃ = 4.000495416149978
いずれも概ね4を返した. どのパッケージも積分値だけでなく誤差やその他の情報を一緒に返してくるため, 最後に[1]
や.integral_estimate
を加えて積分値を抜き出している. また, HCubature.jl, MonteCarloIntegration.jlは多変数を前提として開発されているので, 1変数の場合でもx
は配列であると考えて x[1]^3
と書く. 次に
I₁ = (
quadgk(y ->
quadgk(x ->
x^3 + y
, 0, 2, maxevals=10^3)[1]
, 0, 1, maxevals=10^3)[1]
) # QuadGK.jl
I₂ = hcubature(x -> x[1]^3 + x[2], [0,0], [2,1])[1] # HCubature.jl
I₃ = vegas(x -> x[1]^3 + x[2], [0,0], [2,1]).integral_estimate # MonteCarloIntegration.jl
@show I₁
@show I₂
@show I₃
# output
I₁ = 5.0
I₂ = 4.999999999999999
I₃ = 5.00545791767893
いずれも概ね5を返した. QuadGK.jlには1変数のルーチンしかないはずなので, 2重に使って2変数に対応する. 以下では積分公式を検証していく.
ガウス積分
証明は非常に有名であり, Wikipediaにも載っているので省略する.
下記のように解析的な積分と数値積分との誤差率が0.01%以内であれば✔を表示する.
println("a | analytical | QuadGK.jl ")
println("------ | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)
numerical = quadgk(x -> exp(-a*x^2), -Inf, Inf, rtol=1e-12, maxevals=10^7)[1]
@printf("%6.2f | %17.12f | %17.12f %s\n", a, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
a | analytical | QuadGK.jl
------ | ----------------- | -----------------
0.01 | 17.724538509055 | 17.724538509055 ✔
0.10 | 5.604991216398 | 5.604991216398 ✔
1.00 | 1.772453850906 | 1.772453850906 ✔
10.00 | 0.560499121640 | 0.560499121640 ✔
100.00 | 0.177245385091 | 0.177245385091 ✔
一般化されたガウス積分
1次元において, ガウス積分を下記のように一般化する.
ここでは通常のガウス積分は
が与えられているので
が得られる. 英語版のWikipediaに載っているのを見つけた. また
# using SpecialFunctions # for gamma()
GGI(n,a) = gamma((n+1)/2) / (2*a^((n+1)/2))
println("a | n | analytical | QuadGK.jl ")
println("------ | --- | ----------------- | -----------------")
for a in [0.5, 1.0, 10.0, 100.0]
for n in 0:10
analytical = GGI(n,a)
numerical = quadgk(x -> x^n * exp(-a*x^2), 0, Inf, maxevals=10^3)[1]
@printf("%6.2f | %3d | %17.12f | %17.12f %s\n", a, n, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
end
a | n | analytical | QuadGK.jl
------ | --- | ----------------- | -----------------
0.50 | 0 | 1.253314137316 | 1.253314137316 ✔
0.50 | 1 | 1.000000000000 | 1.000000000000 ✔
0.50 | 2 | 1.253314137316 | 1.253314137316 ✔
0.50 | 3 | 2.000000000000 | 2.000000000000 ✔
0.50 | 4 | 3.759942411947 | 3.759942411947 ✔
0.50 | 5 | 8.000000000000 | 8.000000000000 ✔
0.50 | 6 | 18.799712059733 | 18.799712059733 ✔
0.50 | 7 | 48.000000000000 | 48.000000000002 ✔
0.50 | 8 | 131.597984418128 | 131.597984418140 ✔
0.50 | 9 | 384.000000000000 | 384.000000000000 ✔
0.50 | 10 | 1184.381859763148 | 1184.381859763148 ✔
1.00 | 0 | 0.886226925453 | 0.886226925453 ✔
1.00 | 1 | 0.500000000000 | 0.500000000000 ✔
1.00 | 2 | 0.443113462726 | 0.443113462726 ✔
1.00 | 3 | 0.500000000000 | 0.500000000000 ✔
1.00 | 4 | 0.664670194090 | 0.664670194090 ✔
1.00 | 5 | 1.000000000000 | 1.000000000000 ✔
1.00 | 6 | 1.661675485224 | 1.661675485224 ✔
1.00 | 7 | 3.000000000000 | 3.000000000000 ✔
1.00 | 8 | 5.815864198284 | 5.815864198284 ✔
1.00 | 9 | 12.000000000000 | 12.000000000000 ✔
1.00 | 10 | 26.171388892277 | 26.171388892277 ✔
10.00 | 0 | 0.280249560820 | 0.280249560820 ✔
10.00 | 1 | 0.050000000000 | 0.050000000000 ✔
10.00 | 2 | 0.014012478041 | 0.014012478041 ✔
10.00 | 3 | 0.005000000000 | 0.005000000000 ✔
10.00 | 4 | 0.002101871706 | 0.002101871706 ✔
10.00 | 5 | 0.001000000000 | 0.001000000000 ✔
10.00 | 6 | 0.000525467927 | 0.000525467927 ✔
10.00 | 7 | 0.000300000000 | 0.000300000000 ✔
10.00 | 8 | 0.000183913774 | 0.000183913774 ✔
10.00 | 9 | 0.000120000000 | 0.000120000000 ✔
10.00 | 10 | 0.000082761198 | 0.000082761198 ✔
100.00 | 0 | 0.088622692545 | 0.088622692545 ✔
100.00 | 1 | 0.005000000000 | 0.005000000000 ✔
100.00 | 2 | 0.000443113463 | 0.000443113463 ✔
100.00 | 3 | 0.000050000000 | 0.000050000000 ✔
100.00 | 4 | 0.000006646702 | 0.000006646702 ✔
100.00 | 5 | 0.000001000000 | 0.000001000000 ✔
100.00 | 6 | 0.000000166168 | 0.000000166168 ✔
100.00 | 7 | 0.000000030000 | 0.000000030000 ✔
100.00 | 8 | 0.000000005816 | 0.000000005816 ✔
100.00 | 9 | 0.000000001200 | 0.000000001200 ✔
100.00 | 10 | 0.000000000262 | 0.000000000262 ✔
もっと一般化されたガウス積分
More Generalized Gaussian Integralを次のように定義する.
ここで
# using SpecialFunctions # for gamma()
# using GSL # for sf_hyperg_U()
# MGGI(n,a,b) = a*gamma(1+n)/(2^(2+n)*b^(1+n/2)) * HypergeometricFunctions.U(1+n/2,3/2,a^2/4/b)
MGGI(n,a,b) = a/(2^(n+2)*b^(n/2+1)) * GSL.sf_hyperg_U(n/2+1,3/2,a^2/4/b) * gamma(n+1)
println("a | b | n | analytical | QuadGK.jl ")
println("------ | ------ | --- | ----------------- | -----------------")
for a in [0.1, 1.0, 10.0]
for b in [0.1, 1.0, 10.0]
for n in 0:10
analytical = MGGI(n,a,b)
numerical = quadgk(x -> x^n * exp(-a*x - b*x^2), 0, Inf, maxevals=10^3)[1]
@printf("%6.2f | %6.2f | %3d | %17.12f | %17.12f %s\n", a, b, n, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
end
end
a | b | n | analytical | QuadGK.jl
------ | ------ | --- | ----------------- | -----------------
0.10 | 0.10 | 0 | 2.365023857063 | 2.365023857063 ✔
0.10 | 0.10 | 1 | 3.817488071469 | 3.817488071469 ✔
0.10 | 0.10 | 2 | 9.916375249581 | 9.916375249581 ✔
0.10 | 0.10 | 3 | 33.216693089895 | 33.216693089895 ✔
0.10 | 0.10 | 4 | 132.137282198762 | 132.137282198762 ✔
0.10 | 0.10 | 5 | 598.265220698515 | 598.265220698516 ✔
0.10 | 0.10 | 6 | 3004.299444619790 | 3004.299444619781 ✔
0.10 | 0.10 | 7 | 16445.806898645555 | 16445.806898645282 ✔
0.10 | 0.10 | 8 | 96927.577112369851 | 96927.577112362909 ✔
0.10 | 0.10 | 9 | 609368.487389638554 | 609368.487389637972 ✔
0.10 | 0.10 | 10 | 4057056.726361821406 | 4057056.726361818612 ✔
0.10 | 1.00 | 0 | 0.838361847809 | 0.838361847809 ✔
0.10 | 1.00 | 1 | 0.458081907610 | 0.458081907610 ✔
0.10 | 1.00 | 2 | 0.396276828524 | 0.396276828524 ✔
0.10 | 1.00 | 3 | 0.438268066183 | 0.438268066183 ✔
0.10 | 1.00 | 4 | 0.572501839477 | 0.572501839477 ✔
0.10 | 1.00 | 5 | 0.847911040393 | 0.847911040393 ✔
0.10 | 1.00 | 6 | 1.388859046672 | 1.388859046672 ✔
0.10 | 1.00 | 7 | 2.474290168845 | 2.474290168845 ✔
0.10 | 1.00 | 8 | 4.737292154909 | 4.737292154909 ✔
0.10 | 1.00 | 9 | 9.660296067635 | 9.660296067635 ✔
0.10 | 1.00 | 10 | 20.834799893709 | 20.834799893709 ✔
0.10 | 10.00 | 0 | 0.275318798552 | 0.275318798552 ✔
0.10 | 10.00 | 1 | 0.048623406007 | 0.048623406007 ✔
0.10 | 10.00 | 2 | 0.013522822898 | 0.013522822898 ✔
0.10 | 10.00 | 3 | 0.004794726486 | 0.004794726486 ✔
0.10 | 10.00 | 4 | 0.002004449802 | 0.002004449802 ✔
0.10 | 10.00 | 5 | 0.000948923048 | 0.000948923048 ✔
0.10 | 10.00 | 6 | 0.000496367835 | 0.000496367835 ✔
0.10 | 10.00 | 7 | 0.000282195075 | 0.000282195075 ✔
0.10 | 10.00 | 8 | 0.000172317767 | 0.000172317767 ✔
0.10 | 10.00 | 9 | 0.000112016441 | 0.000112016441 ✔
0.10 | 10.00 | 10 | 0.000076982913 | 0.000076982913 ✔
1.00 | 0.10 | 0 | 0.865392586515 | 0.865392586515 ✔
1.00 | 0.10 | 1 | 0.673037067424 | 0.673037067424 ✔
1.00 | 0.10 | 2 | 0.961777595453 | 0.961777595453 ✔
1.00 | 0.10 | 3 | 1.921482696980 | 1.921482696980 ✔
1.00 | 0.10 | 4 | 4.819250446898 | 4.819250446898 ✔
1.00 | 0.10 | 5 | 14.333401705099 | 14.333401705099 ✔
1.00 | 0.10 | 6 | 48.814252646962 | 48.814252646962 ✔
1.00 | 0.10 | 7 | 185.930787918163 | 185.930787918163 ✔
1.00 | 0.10 | 8 | 778.844903052866 | 778.844903052855 ✔
1.00 | 0.10 | 9 | 3543.007001462193 | 3543.007001462197 ✔
1.00 | 0.10 | 10 | 17332.985630067957 | 17332.985630067997 ✔
1.00 | 1.00 | 0 | 0.545641360765 | 0.545641360765 ✔
1.00 | 1.00 | 1 | 0.227179319617 | 0.227179319617 ✔
1.00 | 1.00 | 2 | 0.159231020574 | 0.159231020574 ✔
1.00 | 1.00 | 3 | 0.147563809331 | 0.147563809331 ✔
1.00 | 1.00 | 4 | 0.165064626195 | 0.165064626195 ✔
1.00 | 1.00 | 5 | 0.212595305563 | 0.212595305563 ✔
1.00 | 1.00 | 6 | 0.306363912707 | 0.306363912707 ✔
1.00 | 1.00 | 7 | 0.484603960337 | 0.484603960337 ✔
1.00 | 1.00 | 8 | 0.829971714305 | 0.829971714305 ✔
1.00 | 1.00 | 9 | 1.523429984196 | 1.523429984196 ✔
1.00 | 1.00 | 10 | 2.973157722275 | 2.973157722275 ✔
1.00 | 10.00 | 0 | 0.236502385706 | 0.236502385706 ✔
1.00 | 10.00 | 1 | 0.038174880715 | 0.038174880715 ✔
1.00 | 10.00 | 2 | 0.009916375250 | 0.009916375250 ✔
1.00 | 10.00 | 3 | 0.003321669309 | 0.003321669309 ✔
1.00 | 10.00 | 4 | 0.001321372822 | 0.001321372822 ✔
1.00 | 10.00 | 5 | 0.000598265221 | 0.000598265221 ✔
1.00 | 10.00 | 6 | 0.000300429944 | 0.000300429944 ✔
1.00 | 10.00 | 7 | 0.000164458069 | 0.000164458069 ✔
1.00 | 10.00 | 8 | 0.000096927577 | 0.000096927577 ✔
1.00 | 10.00 | 9 | 0.000060936849 | 0.000060936849 ✔
1.00 | 10.00 | 10 | 0.000040570567 | 0.000040570567 ✔
10.00 | 0.10 | 0 | 0.099801188165 | 0.099801188165 ✔
10.00 | 0.10 | 1 | 0.009940591748 | 0.009940591748 ✔
10.00 | 0.10 | 2 | 0.001976353427 | 0.001976353427 ✔
10.00 | 0.10 | 3 | 0.000588246113 | 0.000588246113 ✔
10.00 | 0.10 | 4 | 0.000232995745 | 0.000232995745 ✔
10.00 | 0.10 | 5 | 0.000115135036 | 0.000115135036 ✔
10.00 | 0.10 | 6 | 0.000068141803 | 0.000068141803 ✔
10.00 | 0.10 | 7 | 0.000046960922 | 0.000046960922 ✔
10.00 | 0.10 | 8 | 0.000036916993 | 0.000036916993 ✔
10.00 | 0.10 | 9 | 0.000032587264 | 0.000032587264 ✔
10.00 | 0.10 | 10 | 0.000031901484 | 0.000031901484 ✔
10.00 | 1.00 | 0 | 0.098109430732 | 0.098109430732 ✔
10.00 | 1.00 | 1 | 0.009452846342 | 0.009452846342 ✔
10.00 | 1.00 | 2 | 0.001790483654 | 0.001790483654 ✔
10.00 | 1.00 | 3 | 0.000500428071 | 0.000500428071 ✔
10.00 | 1.00 | 4 | 0.000183585126 | 0.000183585126 ✔
10.00 | 1.00 | 5 | 0.000082930513 | 0.000082930513 ✔
10.00 | 1.00 | 6 | 0.000044310249 | 0.000044310249 ✔
10.00 | 1.00 | 7 | 0.000027240296 | 0.000027240296 ✔
10.00 | 1.00 | 8 | 0.000018884388 | 0.000018884388 ✔
10.00 | 1.00 | 9 | 0.000014539246 | 0.000014539246 ✔
10.00 | 1.00 | 10 | 0.000012283518 | 0.000012283518 ✔
10.00 | 10.00 | 0 | 0.086539258652 | 0.086539258652 ✔
10.00 | 10.00 | 1 | 0.006730370674 | 0.006730370674 ✔
10.00 | 10.00 | 2 | 0.000961777595 | 0.000961777595 ✔
10.00 | 10.00 | 3 | 0.000192148270 | 0.000192148270 ✔
10.00 | 10.00 | 4 | 0.000048192504 | 0.000048192504 ✔
10.00 | 10.00 | 5 | 0.000014333402 | 0.000014333402 ✔
10.00 | 10.00 | 6 | 0.000004881425 | 0.000004881425 ✔
10.00 | 10.00 | 7 | 0.000001859308 | 0.000001859308 ✔
10.00 | 10.00 | 8 | 0.000000778845 | 0.000000778845 ✔
10.00 | 10.00 | 9 | 0.000000354301 | 0.000000354301 ✔
10.00 | 10.00 | 10 | 0.000000173330 | 0.000000173330 ✔
2次元のガウス積分
以下では, 上記の2の一般化とは異なり, 次元を増やすという意味での一般化を考える. 2次元の積分は逐次的に
println("a | analytical | QuadGK.jl ")
println("------ | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)^2
numerical = (
quadgk(y ->
quadgk(x ->
exp(-a*x^2 -a*y^2)
, -Inf, Inf, maxevals=10^3)[1]
, -Inf, Inf, maxevals=10^3)[1]
)
@printf("%6.2f | %17.12f | %17.12f %s\n", a, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
a | analytical | QuadGK.jl
------ | ----------------- | -----------------
0.01 | 314.159265358979 | 314.159265358887 ✔
0.10 | 31.415926535898 | 31.415926535898 ✔
1.00 | 3.141592653590 | 3.141592653590 ✔
10.00 | 0.314159265359 | 0.314159265359 ✔
100.00 | 0.031415926536 | 0.031415926536 ✔
極座標系におけるガウス積分
次式で与えられる極座標系への変換
ヤコビアンは下記のように計算できる.
なお,
println("a | analytical | QuadGK.jl ")
println("------ | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)^2
numerical = (
quadgk(θ ->
quadgk(r ->
r * exp(-a*r^2)
, 0, Inf, maxevals=10^3)[1]
, 0, 2*π, maxevals=10^3)[1]
)
@printf("%6.2f | %17.12f | %17.12f %s\n", a, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
a | analytical | QuadGK.jl
------ | ----------------- | -----------------
0.01 | 314.159265358979 | 314.159265358979 ✔
0.10 | 31.415926535898 | 31.415926535898 ✔
1.00 | 3.141592653590 | 3.141592653590 ✔
10.00 | 0.314159265359 | 0.314159265359 ✔
100.00 | 0.031415926536 | 0.031415926536 ✔
3次元のガウス積分
3次元でも2次元と同様にして, 単に1次元のガウス積分の3乗となる.
println("a | analytical | QuadGK.jl ")
println("------ | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)^3
numerical = (
quadgk(z ->
quadgk(y ->
quadgk(x ->
exp(-a*x^2 -a*y^2 -a*z^2)
, -Inf, Inf, maxevals=10^3)[1]
, -Inf, Inf, maxevals=10^3)[1]
, -Inf, Inf, maxevals=10^3)[1]
)
@printf("%6.2f | %17.12f | %17.12f %s\n", a, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
a | analytical | QuadGK.jl
------ | ----------------- | -----------------
0.01 | 5568.327996831709 | 5568.327996829265 ✔
0.10 | 176.085992288711 | 176.085992288711 ✔
1.00 | 5.568327996832 | 5.568327996832 ✔
10.00 | 0.176085992289 | 0.176085992289 ✔
100.00 | 0.005568327997 | 0.005568327997 ✔
球面座標系におけるガウス積分
球面座標系への変換
におけるヤコビアンは
のように計算できるから, これを用いて積分領域
と計算できる. なお, 計算には1次元のガウス積分を用いている.
println("a | analytical | QuadGK.jl ")
println("------ | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)^3
numerical = (
quadgk(φ ->
quadgk(θ ->
quadgk(r ->
r^2 * sin(θ) * exp(-a*r^2)
, 0, Inf, maxevals=100)[1]
, 0, π, maxevals=10)[1]
, 0, 2*π, maxevals=20)[1]
)
@printf("%6.2f | %17.12f | %17.12f %s\n", a, analytical, numerical, isapprox(analytical, numerical, rtol=1e-5) ? "✔" : "✗")
end
a | analytical | QuadGK.jl
------ | ----------------- | -----------------
0.01 | 5568.327996831709 | 5567.958330629872 ✗
0.10 | 176.085992288711 | 176.085992503519 ✔
1.00 | 5.568327996832 | 5.568327996978 ✔
10.00 | 0.176085992289 | 0.176085992289 ✔
100.00 | 0.005568327997 | 0.005568327997 ✔
最後にHCubature.jlとMonteCarloIntegration.jlも加えた結果を示す. モンテカルロ法では誤差率の閾値は甘めに1%とした.
println("a | analytical | QuadGK.jl | HCubature.jl | MonteCarloIntegration.jl")
println("------ | ----------------- | ----------------- | ----------------- | -----------------")
for a in [0.01, 0.1, 1.0, 10.0, 100.0]
analytical = sqrt(π/a)^3
I₁ = (
quadgk(φ ->
quadgk(θ ->
quadgk(r ->
r^2 * sin(θ) * exp(-a*r^2)
, 0, Inf, maxevals=200)[1]
, 0, π, maxevals=10)[1]
, 0, 2*π, maxevals=20)[1]
)
I₂ = hcubature(x -> x[1]^2 * sin(x[2]) * exp(-a*x[1]^2), [0,0,0], [100,π,2*π])[1]
I₃ = vegas(x -> x[1]^2 * sin(x[2]) * exp(-a*x[1]^2), [0,0,0], [100,π,2*π]).integral_estimate
@printf("%6.2f | %17.12f | %17.12f %s | %17.12f %s | %17.12f %s \n", a, analytical,
I₁, isapprox(analytical, I₁, rtol=1e-5) ? "✔" : "✗",
I₂, isapprox(analytical, I₂, rtol=1e-5) ? "✔" : "✗",
I₃, isapprox(analytical, I₃, rtol=1e-2) ? "✔" : "✗"
)
end
a | analytical | QuadGK.jl | HCubature.jl | MonteCarloIntegration.jl
------ | ----------------- | ----------------- | ----------------- | -----------------
0.01 | 5568.327996831709 | 5568.327996831707 ✔ | 5568.327997006358 ✔ | 5568.478496127373 ✔
0.10 | 176.085992288711 | 176.085992288711 ✔ | 176.085992294186 ✔ | 176.120007666057 ✔
1.00 | 5.568327996832 | 5.568327996832 ✔ | 5.568327997105 ✔ | 5.561248789741 ✔
10.00 | 0.176085992289 | 0.176085992289 ✔ | 0.176085992297 ✔ | 0.176020030094 ✔
100.00 | 0.005568327997 | 0.005568327997 ✔ | 0.005568327997 ✔ | 0.005567615795 ✔
参考文献
- Wikipedia 日本語版
- Wikipedia 英語版
- 森口繁一, 宇田川銈久, 一松信『岩波 数学公式Ⅰ』(岩波書店,1988,新装第3刷) p.233
- QuadGK.jlドキュメント
- HCubature.jlドキュメント
- MonteCarloIntegration.jlドキュメント
- Wolfram Alpha, GGI, MGGI
おわりに
いかがでしたか? 元々は開発したパッケージの紹介を予定していましたが, 公式パッケージに登録する際になんと名前が似ているパッケージが既にあるという理由で弾かれてしまい, 使用方法やドキュメントに変更が生じるため紹介を延期しました. (間に合えば後日のアドベントカレンダーで紹介する予定です.)
数値積分については, 数式とそのまま対応したコードが書けるQuadGK.jlを気に入って使用しています. 積分の評価回数を減らしたり収束閾値を甘くするなどの工夫をしていますが, やはり3次元の積分が時間を食います. パッケージのテストに使っているためGitHub Actionsの無料時間の枠内で不安を感じない程度には高速化したい思っており, モンテカルロ積分の導入を検討し始めたところです. とはいえ, モンテカルロ積分でも定義域を広くとりすぎるとサンプリングがうまくいかないようなエラーもあるので, うまく積分領域のカットオフを決められないかと考えています.
最後に, 広義積分の公式について数値積分の他に何かよい検算の方法をご存じの方はご教授頂ければ幸いです.
Discussion
「このくらいの差なら入力ミスしないだろうし、Antiq.jlが〜という理由で気に入っているから問題ないはず」とコメントすれば通るかもです!コメント先はJulia slackの#pkg-registrationチャンネルです。(https://github.com/JuliaRegistries/General/pull/96227#issuecomment-1833787594 のコメントに書いてある通りですが)
一方で、命名変更後のAnalyticalSolutions.jlは量子力学モデルのパッケージにしては少し名前が広すぎるような印象も受けるので、別の名前の方が良いかも知れません。
コメント頂きありがとうございます!
AnalyticalSolutions.jlは確かに意味が広すぎ、そして長いので変えようと思っていました。Slackの方にコメントしようかも迷いましたが、結局「Antique.jl」に落ち着きました。3日後に登録されるとのことです! 何か間違ってしまったかもしれないのですが、古い方のプルリクエストが更新されるわけではなく新しいプルリクエストが作られたため、古い方が残ってしまっています。自動的に取り下げる方法が見つからなければSlackでクローズするようお願いするつもりです。
古い方のPRは30日くらいで自動的にcloseされたはずなので放置でOKと思います!
ありがとうございます!このまま様子を見ます!