from sympy.abc import *
from sympy import *
from spb import *
# 以下はグラフを SVG で Notebook にインライン表示させる設定
%config InlineBackend.figure_formats = ['svg']
import matplotlib.pyplot as plt
plt.rcParams['mathtext.fontset'] = 'cm'
$\Omega_{\Lambda} = 0$ の場合の角径距離
\begin{eqnarray}
d_A
&=& \frac{2}{H_0 \Omega_{\rm m}^2 (1+z)^2} \left\{2 – \Omega_{\rm m} + \Omega_{\rm m} z – (2-\Omega_{\rm m}) \sqrt{1 + \Omega_{\rm m} z}\right\}
\end{eqnarray}
以下では $H_0$ を($H_0 = 1$ として)省略し,表記の都合上 $\Omega_{\rm m} \rightarrow \Omega$
def dA(Omega, z):
return 2/(Omega**2*(1+z)**2) * (2-Omega+Omega*z-(2-Omega)*sqrt(1 + Omega*z))
$\Omega_{\rm m} + \Omega_{\Lambda} = 1$ の場合の角径距離
\begin{eqnarray}
d_A
&=& \frac{1}{H_0 (1+z)} \int_0^z \frac{dz}{\sqrt{(1-\Omega_{\rm m}) + \Omega_{\rm m} (1+z)^3} }
\end{eqnarray}
解析的には積分できないので,.evalf()
で数値積分に。(激遅だけど楽ちん。)
def dAL(Omega, z):
return 1/(1+z)*integrate(1/sqrt((1-Omega) + Omega*(1+x)**3), (x, 0, z)).evalf()
$0 \leq z \leq 5$ までのグラフ
初めて dAL(0.3, z)
を plot()
する際にはいろいろ文句を言われるかもしれないが,なんとかグラフは描いてくれる。ものすごく時間がかかるので,辛抱。
%%time
plot((dAL(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0.7$'),
(dA(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0$'),
(dA(1, z), '$\Omega_{m}=1,\, \ \ \,\Omega_{\Lambda}=0$'),
(z, 0, 5),
xlim = (0, 5), ylim = (0, 0.5), title='角径距離',
ylabel = '$H_0\, d_A(z)$');
$ 0 \leq z \leq 20$ までのグラフ
$z$ の範囲を変え,若干の細かな設定を追加してみた。あいかわらず何か警告が出るが,気にせずに。
%%time
p = plot((dAL(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0.7$'),
(dA(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0$'),
(dA(1, z), '$\Omega_{m}=1,\, \ \ \,\Omega_{\Lambda}=0$'),
(z, 0, 20),
xlim = (0, 20), ylim = (0, 0.5), title='角径距離',
ylabel = '$H_0\ d_A(z)$', show = False)
fig, ax = p.fig, p.ax
ax.grid(linestyle='dotted')
# x の主目盛を 5 刻みに
ax.set_xticks([i for i in range(0,21,5)])
# 副目盛も表示
ax.minorticks_on()
# 副目盛には grid をつけない
ax.grid(False, which="minor")
# x の副目盛を 1 刻みに
ax.set_xticks([i for i in range(1,20)], minor = True)
# y の副目盛を 1 刻みに
ax.set_yticks([0.05*i for i in range(1,10)], minor = True);
数値リストにして plot_list()
を使ってグラフを描く
(NumPy を使わずに)dAL(Omega, z)
の数値リストを作成し,plot_list()
で数値データをグラフにしてみる。.evalf()
は変わらないので list_dAL
を求めるのは激遅のままだが,グラフを描く際に,なんだかんだと文句はつけられなくなるので,少しだけ精神的に楽かなと。(それにしても SymPy の数値積分は遅い。)
%%time
list_z = [0.1*i for i in range(201)]
list_dAL = [dAL(0.3, 0.1*i) for i in range(201)]
参考:数値積分としてscipy.integrate.quad()
を使う
.evalf()
を使った SymPy の数値積分があまりにも遅すぎて精神衛生上よろしくないので,SymPy(のみ)を使うという本稿の方針からは逸脱するが,SciPy の数値積分 quad()
を使ってみる。
quad()
を使う際には以下のように,決め事にそって被積分関数を定義してやる。
- 被積分関数は原則 $x$ の1変数関数の決め打ちで。
- $x$ 以外のパラメータにも依存する場合は,$x$ の後に引数として並べる。
quad()
を呼び出す際には,$x$ 以外のパラメータはargs
に入れる。quad()
は(積分値, 推定誤差)
を返すので,積分値のみを知りたいときはそのように。
from scipy.integrate import quad
def f(x, Omega):
return 1/sqrt((1-Omega) + Omega*(1+x)**3)
def dAL2(Omega, z):
tmp = quad(f, 0, z, args=(Omega))
return 1/(1+z)*tmp[0]
# 別解
# ans, err = quad(f, 0, z, args=(Omega))
# return 1/(1+z)* ans
%%time
list_z = [0.1*i for i in range(201)]
list_dAL2 = [dAL2(0.3, 0.1*i) for i in range(201)]
… ということで,SciPy の数値積分 quad()
で計算した $d_A(\Omega, z)$ は約70倍高速であることがわかる。
$0 \leq z \leq 5$ までのグラフ
p1 = plot_list(
list_z, list_dAL2,
'$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0.7$',
xlim = (0, 5), ylim = (0, 0.5),
title='角径距離',
xlabel = '$z$', ylabel = '$H_0\, d_A(z)$',
show = False)
p2 = plot(
(dA(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0$'),
(dA(1, z), '$\Omega_{m}=1,\, \ \ \,\Omega_{\Lambda}=0$'),
(z, 0, 5), show = False)
p = p1 + p2
p.show();
$0 \leq z \leq 20$ までのグラフ
p1 = plot_list(
list_z, list_dAL2,
'$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0.7$',
xlim = (0, 20), ylim = (0, 0.5),
title='角径距離',
xlabel = '$z$', ylabel = '$H_0\, d_A(z)$',
show = False)
p2 = plot(
(dA(0.3, z), '$\Omega_{m}=0.3,\, \Omega_{\Lambda}=0$'),
(dA(1, z), '$\Omega_{m}=1,\, \ \ \,\Omega_{\Lambda}=0$'),
(z, 0, 20), show = False)
p = p1 + p2
fig, ax = p.fig, p.ax
ax.grid(linestyle='dotted')
# x の主目盛を 5 刻みに
ax.set_xticks([i for i in range(0,21,5)])
# 副目盛も表示
ax.minorticks_on()
# 副目盛には grid をつけない
ax.grid(False, which="minor")
# x の副目盛を 1 刻みに
ax.set_xticks([i for i in range(1,20)], minor = True)
# y の副目盛を 1 刻みに
ax.set_yticks([0.05*i for i in range(1,10)], minor = True);