単位の約分と単位の換算について

単位の約分と単位の換算について気づいたことをメモします。

単位の約分について

例えば、気体の状態方程式$pV=nRT$で、体積$V$$1.00\times 10 ^ {-3}\ \mathrm{m} ^ 3$、温度$T$$288\ \mathrm{K}$、分子量$n$$1.00\ \mathrm{mol}$のとき、圧力は次のようになります。

p=\frac{nRT}{V}=\frac{1.00\ \mathrm{mol}*8.31\ \mathrm{J\cdot K^{-1}\cdot mol^{-1}}*288\ \mathrm{K}}{1.00\times 10^{-3}\ \mathrm{m}^3}=2.39\times 10^6\ \mathrm{Pa}

このとき、$\mathrm{J=N\cdot m}$$\mathrm{Pa=N\cdot m ^ {-2}}$ですから、単位部分だけ見れば

\begin{aligned}\frac{\cancel\mathrm{mol}*\mathrm{J\cdot \cancel{K^{-1}}\cdot \cancel {mol^{-1}}}*\cancel\mathrm{K}}{\mathrm{m^3}}&=\frac{\mathrm{N\cdot m}}{\mathrm{m^3}}\\&=\mathrm{Pa}\end{aligned}

と単位の約分ができて、単位部分も含め辻褄が合っています。このように、文字式に単位も含め数値を代入することや、単位は約分できることは中学の物理や化学で最初で教えられることだと思います。

単位の換算について

一方圧力は$\mathrm{Pa}$の他に、水銀柱ミリメートル$\mathrm{mmHg}$で表すこともできます。$1\ \mathrm{Pa}=7.52\times 10 ^ {-3}\ \mathrm{mmHg}$です。この式が単位も含め成り立つとすると、$\mathrm{Pa}$で全体を割って、

1=7.52\times 10^{-3}\ \mathrm{mmHg\cdot Pa^{-1}}

とできるはずです。このとき左辺の$1$には単位はありません。先程の、$p=2.39\times 10 ^ 6\ \mathrm{Pa}$という式の両辺にこの式をかければ、

\begin{aligned}p&=2.39\times 10^6\ \mathrm{Pa}*7.52\times 10^{-3}\ \mathrm{mmHg\cdot Pa^{-1}}\\&=1.80\times10^{4}\ \mathrm{mmHg}\end{aligned}

$\mathrm{mmHg}$に換算できます。このように、「1=数字 [換算後の単位/換算前の単位]」という式を両辺に掛け、単位の約分をすることで単位の換算ができるようになりいます。

3つの単位に関する換算

標準気圧を単位とした$\mathrm{atm}$では$1\ \mathrm{atm}=760\ \mathrm{mmHg}$です。この式を変形して、

\frac{\mathrm{atm}}{\mathrm{mmHg}}=760

という式を作ります。このときも右辺には単位はありません。これを$1\ \mathrm{mmHg}=1.33\times10 ^ 2\ \mathrm{Pa}$の両辺に掛けると

\begin{aligned}1\ \cancel\mathrm{mmHg}*\frac{\mathrm{atm}}{\cancel\mathrm{mmHg}} &= 1\ \mathrm{atm}\\&=1.33\times10^2\ \mathrm{Pa}*760\\&= 1.01\times10^5\ \mathrm{Pa}\end{aligned}

$\mathrm{atm}$$\mathrm{Pa}$の関係式が得られます。このように3つの単位に関する換算でも単位の約分をうまく使うと、見通しよく換算できると思います。

まとめ

「1=数字 [換算後の単位/換算前の単位]」という関係式をいろいろ変形して使うと、見通しよく換算できることが分かりました。ここで挙げた例は単純なので、このような計算をしなくてもすぐに換算できると思いますが、複雑な単位の換算をしなければいけないときは役に立つと思います。




Markdownの数式をKaTeXで高速で表示できるようにした

いままで作ってきた

の変換プログラムをKaTeXに対応させました。はてなブログにそのままTeXの数式を渡すと描写にMathJaxを使うようで、描写がかなり遅いです。数式をKaTeXで変換するようなJavaScriptを入れることで、だいぶ表示を高速化できました。

Markdownはてな記法html

github.com

MarkdownはてなMarkdown

github.com

使い方

どちらもmd_parserフォルダ内のmd_parser.pyを次のようにインポートして使います。

from md_parser import md_parser
md_parser.parse_md_to_hatena(pathlib.Pathオブジェクト,style="default")

styleでスタイルを指定できます。

参考サイト

以下のサイトを参考にさせていただきました。ありがとうございました。

KaTeXのテスト - 七誌の開発日記

はてなブログのキーワード自動リンクを停止する - 0番染色体

ボルツマン因子と正規分布、ガンマ分布、マクスウェル分布の関係

統計力学キャンパス・ゼミ

統計力学キャンパス・ゼミ

マセマの「統計力学 キャンパスゼミ」で統計力学を勉強中なのですが、この本にはマクスウェル分布が出てきません。ただ、少し考えるとボルツマン因子$e ^ {-E/kT}$からマクスウェル分布が出せました。そこで、ボルツマン因子、マクスウェル分布、統計学正規分布、ガンマ分布の関係を整理してみます。

統計学

まず統計の知識を整理します。「久保川達也・現代数理統計学の基礎」を参考にしました。

分布関数と確率密度関数

確率変数$X$分布関数$F _ X(x)$確率密度関数$f _ X(x)=\frac{d}{dx}F _ X(x)$と書きます。この記事では確率変数を大文字、その実現値を小文字で書くことにします。

変数変換

確率変数$X$$Y=g(X)$と変換したとき、Yの確率密度関数$f _ Y(y)$

f_Y(y)=\frac{d}{dy}F_Y(y)=\frac{d}{dy}P(X\in{x|g(x)\le y})

から導かれます。特に、$g(\cdot)$が単調増加、あるいは単調減少関数の場合は次で与えられます。

f_Y(y)=f_X(g^{-1}(y))\frac{1}{|g'(g^{-1}(y))|}

平方変換

確率変数$X$確率密度関数$f _ X(x)$とします。$X$の平方変換$Y=X ^ 2$に対して、Yの確率密度関数

f_Y(y)=\left[f_X(\sqrt{y})+f_X(-\sqrt{y})\right]\frac{1}{2\sqrt{y}}

で与えられます。特に、$f _ X(x)$$y$軸に関し対称なら、$f _ Y(y)=f _ X(\sqrt{y})/\sqrt{y}$となります。

正規分布

確率変数$X$が平均$\mu$、分散$\sigma ^ 2$正規分布に従うとき、$X\sim \mathcal{N}(\mu,\sigma ^ 2)$と書き、$X$確率密度関数は次のようになります。

f_X(x|\mu,\sigma^2)=\frac{1}{\sqrt{2\pi\sigma^2}}\exp{\left[-\frac{(x-\mu)^2}{2\sigma^2}\right]}

ガンマ分布

確率変数$X$確率密度関数が次のように与えられるとき、$X$はガンマ分布に従うといい、$X\sim Ga(\alpha,\beta)$と書きます。

f_X(x|\alpha,\beta)=\frac{1}{\Gamma(\alpha)}\frac{1}{\beta}\left(\frac{x}{\beta}\right)^{\alpha-1}e^{-x/\beta}

$\Gamma(\alpha)$はガンマ関数です。また$X\sim Ga(\alpha,\beta)$の期待値は$\alpha\beta$で分散は$\alpha\beta ^ 2$です。

確率変数が$Z\sim\mathcal{N}(0,\sigma ^ 2)$に従うとき、$Z ^ 2$$Ga(\frac{1}{2},2\sigma ^ 2)$に従います。これは平方変換で導くことができます。また、$\sigma ^ 2=1$のとき、$Z ^ 2\sim Ga(\frac{1}{2},2)$となりますが、これは自由度$1$カイ二乗分布といい、$Z ^ 2\sim \chi _ 1$と表します。

多次元確率分布

2つの確率変数の組$(X,Y)$$(x,y)$周辺となる確率は同時確率密度関数$f _ {X,Y}(x,y)$を用いて表します。$X$単体、$Y$単体の確率密度関数周辺確率密度関数と呼ばれ次のように表します。

f_X(x)=\int_{-\infty}^\infty f_{X,Y}(x,y) dy

確率の独立性

同時確率密度関数がそれぞれの確率密度関数の積で表せるとき、独立であると言います。次の場合$X$$Y$は独立です。

f_{X,Y}(x,y)=f_X(x)f_Y(y)

独立であるということは、$X$$Y$がどんな値になるかに依存せずに、確率密度関数$f _ X(x)$で表される分布に従うということです。

多変数確率変数の変数変換

確率変数$(X,Y)$$S=g _ 1(X,Y)$$T=g _ 2(X,Y)$と変数変換したい場合、$(X,Y)\leftrightarrow(S,T)$が1対1対応なら、$(S,T)$の同時確率密度関数ヤコビアン$J(s,t)$を用いて次のように書けます。

f_{S,T}(s,t)=f_{X,Y}(x(s,t),y(s,t))|J(s,t)|

ガンマ分布に従う確率変数同士の和

独立な確率変数$X$$Y$がそれぞれ$X\sim Ga(\alpha _ 1,\beta)$$Y\sim Ga(\alpha _ 2,\beta)$のとき、その和$Z=X+Y$$Ga(\alpha _ 1+\alpha _ 2,\beta)$に従います。

ボルツマン因子とマクスウェル分布の関係

統計力学 キャンパスゼミ」p69の結合系の熱浴の理論、またはp76のカノニカル・アンサンブル理論からエネルギーの確率はボルツマン因子$e ^ {-E/kT}$に比例します。ここで$k$ボルツマン定数$T$は温度です。$\pmb{q}$を一般化座標、$\pmb{p}$を一般化運動量とし、位相空間上の点$(\pmb{q},\pmb{p})$でエネルギーが$E(\pmb{q},\pmb{p})$となる確率密度$f(\pmb{q},\pmb{p})$は次のように与えられます。

f(\pmb{q},\pmb{p})=\frac{e^{-E/kT}}{\int\int_{-\infty}^\infty e^{-E/kT} d\pmb{q} d\pmb{p} }

注意しなくてはならないのが、これは変数が$(\pmb{q},\pmb{p})$である関数なので、$E$の確率密度を表していますが、$E$を変数にとる確率密度関数にはなっていない点です。(次に示しますが、自由粒子の場合は$E$確率密度関数はガンマ分布となります。)

$x$方向にしか動かない1自由粒子の場合

質量$m$の1つの粒子が$x$方向にしか動かない1次元運動をしている場合、$x$方向の運動量を$p _ x$としてエネルギーは次のように表せます。

E=\frac{1}{2m}p_x^2

これをボルツマン因子の式に代入すれば、係数を$A$として確率密度関数は次のように表せます。

f(p_x)=A\exp{\left[-\frac{p_x^2}{2mkT}\right]}

係数$A$はこの確率密度関数$p _ x$積分したときに$1$になるようにすればよく、$p _ x$についての関数の形に注目すればこれは正規分布と同じ形です。したがって、$p _ x$$\mathcal{N}(0,mkT)$に従うと言えます。(ボルツマン因子の式はエネルギー$E$についての確率密度なのにここで$p _ x$についての確率密度関数としてしまっているのは不正確な気がしますが無視します。)

よって、$p _ x ^ 2$はガンマ分布$Ga(\frac{1}{2},2mkT)$に従います。よってエネルギー$E=\frac{1}{2m}p _ x ^ 2$は変数変換を考えれば$Ga(\frac{1}{2},kT)$に従います。ガンマ分布$Ga(\alpha,\beta)$の期待値は$\alpha\beta$でしたので、1次元自由粒子のエネルギーの期待値$\langle E\rangle$

\langle E\rangle=\frac{1}{2}kT

となります。

2次元1自由粒子の場合

次に$x$$y$方向に2次元運動をしている自由粒子について考えます。エネルギーは次のように表せます。

E=\frac{1}{2m}\left(p_x^2+p_y^2\right)

これをボルツマン因子の式に代入すれば、係数を$A$として$(p _ x,p _ y)$の同時確率密度関数は次のように表せます。

\begin{aligned}f(p_x,p_y)&=A\exp{\left[-\frac{p_x^2+p_y^2}{2mkT}\right]}\\&=\sqrt{A}\exp{\left[-\frac{p_x^2}{2mkT}\right]}\sqrt{A}\exp{\left[-\frac{p_y^2}{2mkT}\right]}\end{aligned}

同時確率密度関数$p _ x$$p _ y$の関数の積の形に書けたので、$p _ x$$p _ y$は独立で、それぞれ$\mathcal{N}(0,mkT)$に従います。よって$p _ x ^ 2$$p _ y ^ 2$は独立にガンマ分布$Ga(\frac{1}{2},2mkT)$に従います。よってガンマ分布に従う確率変数同士の和の性質から

\begin{aligned}p_x^2+p_y^2&\sim Ga(1,2mkT)\\E=\frac{p_x^2+p_y^2}{2m}&\sim Ga(1,kT)\end{aligned}

よって2次元自由粒子のエネルギーの期待値$\langle E\rangle$

\langle E\rangle=kT

となります。

ただ、「確率密度の関数が運動量の関数の積の形に表せた→独立だからそれぞれ正規分布に従う→よってエネルギーはガンマ分布に従う」(※)というのはちょっと納得できない部分もあるので、変数変換で直接エネルギーの確率密度関数を導出してみます。

(※)の証明

確率変数$X,Y$についての多変数正規分布確率密度関数

\begin{aligned}f_{X,Y}(x,y)&=\frac{a}{\pi}e^{-a(x^2+y^2)}\\&=\sqrt{\frac{a}{\pi}}e^{-ax^2}\sqrt{\frac{a}{\pi}}e^{-ay^2}\end{aligned}

を考えます。($\cdots(a1)$)

また、もし$X$,$Y$が独立に$\mathcal{N}(0,1/2a)$に従うなら、$S=X ^ 2+Y ^ 2$$Ga(1,1/a)$に従うと予想されます。$Ga(1,1/a)$確率密度関数

f_X(x|1,\frac{1}{a})=\frac{1}{\Gamma(1)}a(ax)^{1-1}e^{-ax}=ae^{-ax}

となります。($\cdots(a2)$)

$(a1)$$S=X ^ 2+Y ^ 2$と変数変換したときの$S$確率密度関数が、式$(a2)$に一致すれば、(※)は正しいとしてよさそうです。

そこで多変数の変数変換をします。$S=X ^ 2+Y ^ 2$$T=X$とすると、$x=t$$y=\pm\sqrt{s-t ^ 2}$なので

\begin{aligned}J(s,t)=\frac{1}{J(x,y)}&=det^{-1}\begin{pmatrix}\frac{ds}{dx} & \frac{ds}{dy}\\\frac{dt}{dx} & \frac{dt}{dy}\end{pmatrix}\\&=det^{-1}\begin{pmatrix}2x & 2y\\1 & 0\end{pmatrix}\\&=\mp\frac{1}{2\sqrt{s-t^2}}\end{aligned}

ただ、$(X,Y)\leftrightarrow(S,T)$が1対1対応ではありません。多変数の変数変換の式は1対1対応でないと使えないのですが、とりあえず$y\gt 0$の場合のみ考えると、

\begin{aligned}f_{S,T}(s,t;y\gt 0)=f_{X,Y}(x,y)\frac{1}{2\sqrt{s-t^2}}\\=\frac{a}{\pi}\frac{e^{-as}}{2\sqrt{s-t^2}}\end{aligned}

なので、$y\gt 0$の場合の$S$の周辺確率密度関数

f_{S}(s;y\gt 0)=\int_{-\sqrt{S}}^{\sqrt{S}}\frac{a}{\pi}\frac{e^{-as}}{2\sqrt{s-t^2}}dt

ここで$u=t/\sqrt{s}$と変数変換すると$t:-\sqrt{S}\rightarrow\sqrt{S}$$u:-1\rightarrow1$で、$du/ds=1/\sqrt{s}$なので、

\int_{-\sqrt{S}}^{\sqrt{S}}\frac{1}{\sqrt{s-t^2}}dt=\int_{-1}^1\frac{1}{\sqrt{s}}\frac{\sqrt{s}}{\sqrt{1-u^2}}du

さらに$u=\sin\theta$とすれば、$u:-1\rightarrow1$$\theta:-\pi/2\rightarrow\pi/2$で、$du/d\theta=\cos\theta$なので、

\int_{-1}^1\frac{1}{\sqrt{1-u^2}}du=\int_{-\frac{\pi}{2}}^{\frac{\pi}{2}}\frac{\cos\theta}{\sqrt{1-\sin^2{\theta}}}d\theta=\pi

となります。よって、

f_S(s;y\gt 0)=\frac{a}{2}e^{-as}

となります。$y\lt 0$の場合も同じ式が出てくるので、単純この式を2倍すればいいとすれば、

f_S(s)=ae^{-as}

となります。よって式$(a2)$と一致しました。よって、「確率密度の関数が運動量の関数の積の形にかけた→独立だからそれぞれ正規分布に従う→よってエネルギーはガンマ分布に従う」としてよさそうです。

3次元1自由粒子の場合

次に$x$$y$$z$方向の3次元運動をしている自由粒子について考えます。これまでと同様、$p _ x$$p _ y$$p _ z$は独立で、それぞれ$\mathcal{N}(0,mkT)$に従います。よって$p _ x ^ 2$$p _ y ^ 2$$p _ z ^ 2$は独立にガンマ分布$Ga(\frac{1}{2},2mkT)$に従います。よってガンマ分布に従う確率変数同士の和の性質から

\begin{aligned}p_x^2+p_y^2+p_z^2&\sim Ga(\frac{3}{2},2mkT)\\E=\frac{p_x^2+p_y^2+p_z^2}{2m}&\sim Ga(\frac{3}{2},kT)\end{aligned}

よって3次元自由粒子のエネルギーの期待値$\langle E\rangle$

\langle E\rangle=\frac{3}{2}kT

となります。

マクスウェル分布

いよいよマクスウェル分布を導出します。3次元運動をしている自由粒子の速さ$v(v\ge0)$は、$x$方向の速度が$v _ x=p _ x/m$と表せられることを使って、次のように表せます。

\begin{aligned}v&=\sqrt{v_x^2+v_y^2+v_z^2}\\&=\frac{1}{m}\sqrt{p_x^2+p_y^2+p_z^2}\end{aligned}

ここで$p=\sqrt{p _ x ^ 2+p _ y ^ 2+p _ z ^ 2}$と定義すると$u=p ^ 2$はガンマ分布$Ga(3/2,2mkT)$に従います。変数変換によって、$p=\sqrt{u}$確率密度関数を導出してみます。$du/dp=2p$を使い、変数変換の公式を使うと、$p$確率密度関数は次のようになります。

\begin{aligned}f_p(p)&=2pf_u(u)\\&=\frac{2p}{\Gamma(\frac{3}{2})}\frac{1}{2mkT}\left(\frac{u}{2mkT}\right)^{3/2-1}\exp{\left(\frac{-u}{2mkT}\right)}\\&=\sqrt{\frac{2}{\pi}}\frac{p^2}{(mkT)^{3/2}}\exp{\left(\frac{-p^2}{2mkT}\right)}\end{aligned}

さらに$v=p/m$で、$dp/dv=m$を使い変数変換の公式を使うと、速さ$v$確率密度関数

\begin{aligned}f_v(v)&=mf_p(p)\\&=\sqrt{\frac{2}{\pi}}\left(\frac{m}{kT}\right)^{3/2}v^2\exp{\left(\frac{-mv^2}{2kT}\right)}\\&=4\pi v^2\left(\frac{m}{2\pi kT}\right)^{3/2}\exp{\left(\frac{-mv^2}{2kT}\right)}\end{aligned}

となり、↓のWikipediaに乗っているのと同じマクスウェル分布が導出できました。
マクスウェル分布 -Wikipedia-

$N$個の自由粒子の場合

質量$m$$N$個の粒子が3次元運動しているとき、エネルギー$E$は次のようになります。

E=\frac{1}{2m}\left(p_1^2+p_2^2+\cdots+p_{3N}^2\right)

これまでと同様に、$p _ 1,p _ 2,\cdots$は独立で、それぞれ$\mathcal{N}(0,mkT)$に従います。よって$p _ 1 ^ 2,p _ 2 ^ 2,\cdots$は独立にガンマ分布$Ga(\frac{1}{2},2mkT)$に従います。よってガンマ分布に従う確率変数同士の和の性質から

\begin{aligned}p_1^2+p_2+\cdots +p_{3N}^2&\sim Ga(\frac{3N}{2},2mkT)\\E=\frac{p_1^2+p_2+\cdots +p_{3N}}{2m}&\sim Ga(\frac{3N}{2},kT)\end{aligned}

よって$N$個の自由粒子の総エネルギーの期待値$\langle E\rangle$

\langle E\rangle=\frac{3}{2}NkT

となります。

まとめ

今まで出てきた物理量の分布を表にまとめます。

物理量 分布 期待値
自由粒子$x$方向の速度$v _ x$ $\mathcal{N}(0,kT/m)$ $0$
自由粒子$x$方向の運動量$p _ x$ $\mathcal{N}(0,mkT)$ $0$
自由粒子$p _ x ^ 2$ $Ga(\frac{1}{2},2mkT)$ $mkT$
3次元1自由粒子のエネルギー$E$ $Ga(\frac{3}{2},kT)$ $\frac{3}{2}kT$
自由粒子の速さ$v=\sqrt{v _ x ^ 2+v _ y ^ 2+v _ z ^ 2}$ マクスウェル分布 $\sqrt{\frac{8kT}{\pi m}}$
$N$個の自由粒子の総エネルギー$E$ $Ga(\frac{3N}{2},kT)$ $\frac{3}{2}NkT$

感想

ボルツマン因子$e ^ {-E/kT}$からマクスウェル分布が導出できました。

ただ、ボルツマン因子は熱浴の議論やカノニカルアンサンブル理論から導出されるもので、指数のエネルギー(ハミルトニアン)$E$の形に依りません。なので外力がかかったりして$E$の形が変わっても使えます。

一方、マクスウェル分布は自由粒子の仮定のもと導出したので、自由粒子でない場合はマクスウェル分布はそのままでは使えないです(ように思えます)。ボルツマン因子の方がマクスウェル分布より汎用的であるといえそうです。




Markdownをはてな流Markdownにパースする

Markdown中の数式をてなブログのはてな流の数式に変換するプログラムをつくりました。Markdownファイル全体を一括で変換します。

GitHub - SolKul/md_2_hatena_md

使用方法

md_parserフォルダ内のmd_parser.pyを次のようにインポートして使います。

from md_parser import md_parser
md_parser.parse_md_to_hatena(pathlib.Pathオブジェクト,style="default")

styleでスタイルを指定できます。

レポジトリ内のmain.pyを実行するとSample.mdがパースされ、パースされたSample_hatena.mdというファイルができるはずです。

動機

Markdownはてな記法(html)に変換したり、その中に含まれる数式をSVG形式にして軽くしたりといろいろやってきました。

Markdownをはてな記法にパースする - あおいろメモ

数式をSVG化することで表示速度を12倍高速化した - あおいろメモ

しかし、はてな記法はhtmlなので、後からちょっと誤字脱字を直したいといったちょっとした編集をする際にどこを直せばいいか分かりにくいといった難点があります。また、数式が大量にある記事の場合ははてな記法を使って数式をSVG化して軽くした方がいいですが、大量に数式がない場合ははてな記法を持ち出さなくてもMarkdownでお手軽に書けた方が嬉しいです。そこで、このようなプログラムを作りました。

そもそもはてなブログMarkdown

  • 画面半々にしてプレビューできるがスクロールが同期しない
  • 数式がプレビューされない
  • 数式の記法がLaTeXの普通の記法と異なる(キャレット、アンダーバーなど)
  • いろいろ特有のクセがある(後述)

と使いにくいです。

VSCodeMarkdownを書く

そこで、VSCode拡張機能の一つであるMarkdown Preview EnhancedMarkdownをプレビューしながら文章や数式を書き、それをはてな流のMarkdownに変換することにします。

f:id:SolKul:20210131114414p:plain
VSCodeでのMPEのMarkdown編集画面とプレビュー画面。はてなブログよりかなり優秀。

これを使えば数式を含むQiitaの記事をはてなブログに移植するのも楽になると思います。

Markdown Preview Enhancedについてはこちら

Visual Studio Code + markdown preview enhanced は最高なノートだと思う - Qiita

ただ、はてなブログMarkdown特有のクセには注意が必要です。たとえば、箇条書きの直後に番号付きリストをつけるとバグる、バッククォートを含むコードがコードブロックで書けないなどなど。注意しましょう。

数式の記法

Markdown Preview Enhancedではいくつかの数式の挿入方法がサポートされていますが、そのうち$$で囲まれたブロック数式、$で囲まれたインライン数式に対応しています。しかし、

​```math
e^{i\pi} = -1
​```

には対応していません。

実装

もとのmdファイルをリスト化し、文章全体を標準ブロック、数式ブロックなどとブロックごとのリストに分けてます。標準ブロックについては標準ブロック内のインライン数式をre.findallですべて検索し、順次はてな流インライン数式に変換します。数式ブロックにつていもはてなブログ用の数式ブロックになるように変換します。最後に"".join()で結合し、保存しています。

数式の変換については(styledefaultを指定した場合)

  • ブロック数式($$で囲まれた数式)

については

  1. <div align="center">[tex:]</div>で囲む
  2. ]\]に置換
  3. <>\lt\gtに変換

と変換します。

  • インライン数式($で囲まれた数式)

については

  1. [tex:\displaystyle{}]で囲む
  2. ^(指数)の後ろにスペースを挿入
  3. _(添え字)の前後にスペースを挿入
  4. \{,\},]\\{,\\},\\]に置換
  5. <>\lt\gtに変換

必要環境

python3.8以上。pathilibモジュールを使います。

参考サイト

以下のサイトを参考にさせていただきました。ありがとうございました。

はてなブログで数式を書く - 七誌の開発日記

Latexをはてなブログmarkdown形式に変換 - ano3のブログ

射影平面をいくつかの方法で図示してみる

射影平面をいくつかの方法で図示してみる

こんにちはSolKulです。

今、この参考書で多視点幾何学について勉強しています。

Multiple View Geometry in Computer Vision Second Edition

この参考書のPrefaceの1.1での射影幾何学射影平面についての説明が出てきますが、最初読んだとき訳が分かりませんでした。分かりにくい原因は幾何学の理論を図なしで言葉だけで説明しようとしているためだと思われます。その後いろいろ調べ、射影空間のうち二次元射影空間である射影平面について、いくつかの方法で図示できることがわかったのでメモしておきます。

射影空間の導入

普段我々が慣れ親しんでいる空間の取り扱い方は、ユークリッド幾何学と呼ばれます。平面上の座標を$(x,y)$と2つの数で表すようなやり方です。しかし、このユークリッド幾何学には一つ大きな欠点があります。それは「2つの直線は1点で交わる」という法則に例外を作らないといけないという点です。その例外というのは平行です。平行な直線同士はどこまで行っても交わりません。

例外を回避するために、平行な直線は無限遠の点で交わると定義すればいいかもしれませんが、今度は無限遠の点が厳密に定義できません。このようなユークリッド幾何学の欠点を解決するために、ユークリッド空間に加えて無限遠の点も考慮する空間を考えます。これを射影空間と呼びます。

具体的には、通常、ユークリッド2次元空間上の点は$(x,y)$で表せられますが、射影空間ではそこに1つ座標を加えて$(x,y,1)$と表すことにします。また、3つの数の組で表せられる射影空間の座標は定数倍しても同じものを表すと定義します。つまり$(x,y,1)$$(2x,2y,2)$も同じ点を表します。数学的に正式には、「定数倍した3つの数の組の座標同士が同値であるとしたとき、ユークリッド平面の点はの3つの数の組の座標の同値類(equivalent class)で表せられる」と言います。このような座標のことを同次座標(homogeneous coordinate)と呼びます。

$(x,y,1)$は最後の$1$を除くことでいつでも$(x,y)$ともとのユークリッドの表現に戻すことができますが、$(x,y,0)$についてはどうでしょう?これに対応するもとのユークリッドの座標は存在しません。もし、最後の3つの目の座標で、前2つの座標を割ろうとすれば、$(x/0,y/0)$となり、これは無限になります。こうして考慮に入れたかった無限遠の点が現れてくのです。

以上のことはどんな次元でも同様で、ユークリッド空間$\mathbb{R} ^ n$は、点を同次ベクトルとして表すことで、射影空間$\mathbb{P} ^ n$に拡張する事ができます。また、先程出てきた無限遠点は$\mathbb{P} ^ 2$では直線となることが明らかになります。それを無限遠直線(The line at infinity)と呼びます。また、3次元射影空間$\mathbb{P} ^ 3$では無限遠点は無限遠平面(The plane of infinity)となります。

射影平面の図示

射影平面$\mathbb{P} ^ 2$ユークリッド平面を拡張した概念なので、図示の仕方は1通りではありません。ここではいくつかの図示の方法を示します。

平らな地面を撮った写真

ユークリッド空間にとって無限遠点は特別な存在でしたが、射影空間では無限遠点も考慮に入れているので、なんら特別でなく、すべての点は等しく扱われます。また平行線というのは無限遠点で交わる線です。よって無限遠点が特別な点ではないので、射影空間では線の平行性の概念はありません。 平行であることは射影幾何学の概念ではないと言えます。

このことを頭に入れて、図を書いてみます。図を書く手順は、白い紙を用意し、それが無限に広がっていると想像します。これが射影平面$\mathbb{P} ^ 2$だと考えるのです。まず、

  1. 紙に直線を描き、これが無限遠直線であることを宣言します。無限遠点は特別な存在ではないので、紙の上に適当に書いてもいいはずです。

  2. 次に、この無限遠直線で交差する他の2本の線を描画します。それらは「無限遠直線」で出会うので、平行であると定義できます。(さっき平行の概念はないといったのに、平行を定義しているのはなんか変ですが、細かいことは気にしないようにします。)

これを図示すると以下のようになります。

射影平面の図示1:適当に無限遠直線を定義する方法

どう見ても平行ではない線を平行だと定義する、おかしな図になってしまっています。しかし皆さんはこのようなおかしな状況を1度は目にした事はあるのではないでしょうか。

平行な線路が水平線上で交わっている ©MikeMalak 2006

実はこの図は平らな地面を写真を撮ったときと同じようなものです。無限遠点は水平線上に存在します。そして線路のような地面の上では平行な2つの直線は写真上では水平線上で交わるように見えます。かなり強引な解釈すれば、地面というユークリッド平面を、写真という射影平面に射影したとも言えなくもないです。

平面に単純に無限遠点を加える

先程は平行でない線を平行と定義してしまいましたが、今度は平行は平行のままで図示する方法です。

平面とその周りに円を書きます。この円を無限遠直線とします。平面に平行な線を書いてみます。そしてその平行な線は無限遠点で交わるのですから、周りの円の上にその平行な直線に対応する無限遠点が一つあるはずです。別の方向の平行な直線についても対応する無限遠点が無限遠直線上にあります。

射影平面の図示2:無限遠直線で囲む方法

直線が途中で無理やり折れ曲がっていたり、無限遠直線が曲がっていたりとこれも少し変な図になっています。

半球を貼り合わせたもの

いままでの図示では平行や無限遠点が出てきてしまっていました。本来、射影平面ではすべての点は等しく扱われ、平行という概念はないはずです。そのような図示の仕方を考えます。

半球を考えます。半球にまっすぐな線をひこうとすると、球に沿って曲がってしまいますが、半球の上に立っている小人から見ればほぼ直線です。また半球は貼り合わさられており(図示できないですが)、半球の端の点は反対側の端の点と同一視します。オレンジの直線は半球の端で反対側のオレンジの点にワープする感じです。そしてこの半球上の2つの直線は必ず一点で交わります。

射影平面の図示3:半球で考える方法

この考え方であれば、平行も無限遠点も出てこず、すべての点と直線は等しく扱えます。

3次元空間で原点を通る直線

今度は、「射影空間の導入」の節で説明した同次座標をそのまま表す方法です。

まず3次元空間を考え、ユークリッド平面を$z=1$の平面に対応させます。ユークリッド平面上の点を図のように3次元空間上の原点を通る直線に対応させます。説明したように、射影平面では「定数倍した3つの数の組の座標同士が同値であるとしたとき、ユークリッド平面の点はの3つの数の組の座標の同値類(equivalent class)で表せられる」と言いました。この直線は定数倍した3つの数の組の座標の集合ですので、これがまさに同値類です。

射影平面の図示4:3次元空間で考える方法

そして平行とその交点はどうなるのでしょうか?まず、下図のように2つ直線の交点を考えてみます。この図示の方法ではこの交点は原点を通る直線に対応します。この2つの直線を徐々に平行に近づけていくとどうなるでしょうか?その交点は矢印の方向へ向かうように思えます。

2つの直線を平行に近づけていく

そして最終的に2つの直線が平行になると、交点に対応する直線は、$z=0$の平面上に横倒しになるように思えます。

ついに平行になったとき

この$z=0$の平面上の直線がユークリッド平面にとっての無限遠点となります。これは同次座標の$(x,y,0)$無限遠点だと説明したこととも一致します。

そしてこの図示の方法を使えば無限遠点の集合が直線になることも説明できます。直線がユークリッド平面の点に対応するのですから、平面はユークリッド平面の直線に対応するはずです。実際、原点を通る平面をと$z=1$の平面が交差を考えればそれは直線となります。そして先ほど説明した無限遠点に対応する$z=0$の平面上の直線を集めれば、$z=0$平面となります。平面はユークリッド平面での直線に対応するのですから、無限遠点の集合は直線、つまり無限遠直線(The line at infinity)となります。

この最後の図示の方法は同次座標との対応が取れるので厳密な議論に向いているそうです。

終わりに

もっと射影空間を理解したかったのなら多様体の教科書をよんだほうがいいかもしれません。私もこの記事を書いている途中でこれらの図示をする時間があればその時間を使って多様体の教科書を読んだほうがいいんじゃないかと思い始めました。しかし、個人的にきれいな図を残して知識を整理してみたかったのでこの記事を作ってみました。

射影空間について理解したいときに参考になれば幸いです。

参考にしたサイト

射影平面の3通りの定義 | 高校数学の美しい物語

一次元のトンネル効果(後編)

1次元のトンネル効果の導出 - あおいろメモ

前編では参考書p124式(13b)'の導出までを行ったが、後編では5-14図の図示の再現までを行う

\left|\frac{C}{A}\right|^2=\left[1+\frac{V_0^2\sinh^2\alpha a}{4\varepsilon(V_0-\varepsilon)}\right]^{-1}\tag{13b'}

グラフの図示のために

\varepsilon'=\frac{\varepsilon}{V_0}

とすると、前編の式(13b)'は

\begin{aligned}\left|\frac{C}{A}\right|^2=&\left[1+\frac{\sinh^2\alpha a}{4\varepsilon'(1-\varepsilon')}\right]^{-1}\end{aligned}

となる。また、

\frac{ma^2}{\hbar^2}V_0=8

として式(13b)'の \sinh^2\alpha a の中の \alpha a を計算しておくと、

\begin{aligned}\alpha a&=a\sqrt{\frac{2m}{\hbar^2}(V_0-\varepsilon)}\\&=\sqrt{\frac{2ma^2}{\hbar^2}V_0(1-\varepsilon')}\\&=4\sqrt{1-\varepsilon'}\end{aligned}

よって

\begin{aligned}\left|\frac{C}{A}\right|^2=&\left[1+\frac{\sinh^2 4\sqrt{1-\varepsilon'}}{4\varepsilon'(1-\varepsilon')}\right]^{-1}\end{aligned}

極限

\varepsilon\'\to 0 のとき

\begin{aligned}\lim_{\varepsilon'\to 0}\left|\frac{C}{A}\right|^2&=\lim_{\varepsilon'\to 0}\left[1+\frac{\sinh^2 4\sqrt{1-\varepsilon'}}{4\varepsilon'(1-\varepsilon')}\right]^{-1}\\&=0\end{aligned}

\varepsilon\'\to 1 のとき

4\sqrt{1-\varepsilon'}=\beta

とおくと、

1-\varepsilon'=\frac{\beta^2}{16}
\begin{aligned}\frac{\sinh^2 4\sqrt{1-\varepsilon'}}{4\varepsilon'(1-\varepsilon')}&=4\frac{\sinh^2 \beta}{(1-\beta^2/16)\beta^2}\\&=\frac{4}{1-\beta^2/16}\left(\frac{\sinh \beta}{\beta}\right)^2\end{aligned}

\varepsilon\'\to1 のとき \beta\to0 で、なおかつ、

\lim_{\beta\to0}\frac{\sinh \beta}{\beta}=1

だから、

\begin{aligned}\lim_{\varepsilon'\to 1}\left|\frac{C}{A}\right|^2&=\lim_{\varepsilon'\to 1}\left[1+\frac{\sinh^2 4\sqrt{1-\varepsilon'}}{4\varepsilon'(1-\varepsilon')}\right]^{-1}\\&=\lim_{\beta\to 0}\left[1+\frac{4}{1-\beta^2/16}\left(\frac{\sinh \beta}{\beta}\right)^2\right]^{-1}\\&=(1+4)^{-1}\\&=\frac{1}{5}\end{aligned}

実は \varepsilon>V_0 の場合と式は同じ

\varepsilon>V_0 のときは

\left|\frac{C}{A}\right|^2=\left[ 1+\frac{V_0^2 \sin^2{\kappa a}}{4\varepsilon(\varepsilon-V_0)}\right]^{-1}

であったが、

\kappa a=4\sqrt{\varepsilon'-1}

だから

\left|\frac{C}{A}\right|^2=\left[ 1+\frac{\sin^2{4\sqrt{\varepsilon'-1}}}{4\varepsilon'(\varepsilon'-1)}\right]^{-1}

となるが、実はこれは式(13b)'で、

\sinh{x}=-i\sin{ix}

とすれば導くことができる。よって虚数が表に出ないように別の式にしているだけで \varepsilon>V_0 の場合も、 \varepsilon<V_0 の場合も実は同じ式で表せる。

振幅比が1となる \varepsilon\'

\kappa a=n\pi

\left|\frac{C}{A}\right|^2=1

となるが、このとき、

\varepsilon'=\frac{n^2\pi^2}{16}+1

図示

\frac{ma^2}{\hbar^2}V_0=8

の場合について透過率( |C/A|^2 )を図示する。

\begin{aligned}\left|\frac{C}{A}\right|^2=\left\{\begin{matrix}0& \varepsilon'=0\\\left[ 1+\frac{\sinh^2 4\sqrt{1-\varepsilon'}} {4\varepsilon'(1-\varepsilon')}\right]^{-1} & 0<\varepsilon'<1\\\frac{1}{5}&\varepsilon'=1\\\left[ 1+\frac{\sin^2{4\sqrt{\varepsilon'-1}}} {4\varepsilon'(\varepsilon'-1)}\right]^{-1} & \varepsilon'>1\end{matrix}\right.\end{aligned}

0\le\varepsilon\'\le8 で図示する

\varepsilon'=1
\left|\frac{C}{A}\right|^2=1\quad\therefore\varepsilon'=\frac{n^2\pi^2}{16}+1

となる直線も同時に示す。

f:id:SolKul:20201226233513p:plain
入射エネルギーを変えたときの透過率(振幅比)

\varepsilon\'<1 でも振幅比が0以上となり、粒子の存在確率が漏れ出ている事がわかる。これがトンネル効果である。

数式をSVG化することで表示速度を12倍高速化した

以前、 Markdownをはてな記法にパースする - あおいろメモで、数式を含む記事をはてなブログに快適に投稿できる環境を整えましたが、課題がありました。

MathJaxがクソ重い

MathJaxはJavaScriptでクライアントサイドで本文中の TeX フォーマットを探して全部 SVG に置き換える処理をしています。(参考:サーバーサイド MathJax で数式表示を高速化する | tech - 氾濫原)。なので数式がたくさんある記事をスマホで開こうとするとJavaScriptがフリーズしてしまい見れたものではありませんでした。

スマホのPageSpeedスコア

これは1次元のトンネル効果の導出 - あおいろメモPageSpeedスコアです。ひどいスコアです。自分が持っているスマホ(Galaxy S8)でも読み込みに90秒近くかかり、しかも読み込んだ後もスクロールがガクガクでとてもじゃないけど見れたものではありませんでした。

そこで、あらかじめTeX数式をSVG化してサイトに埋め込んでしまえば、高速化できるのではないかと考え、MarkdownをHTML化し、Markdown中のTeX数式はSVG化するdockerコンテナ群を作りました。

GitHub - SolKul/md_to_html: Convert Markdown to HTML and TeX to SVG

使い方

その1. コンテナを立ち上げます

$ docker-compose up -d

その2. converterコンテナでbashを起動します

$ docker-compose exec converter /bin/bash

その3. converterコンテナ内で main.py を実行します

$ python main.py

python_src内のSample.mdSample.htmlに変換されます

実装

converter と、 node_svgという名前の2つのコンテナを使っています。

converterコンテナにはPython環境が乗っており、Markdown書式をHTMLに変換する自作モジュール、md_pareserを使って、TeX数式以外のMarkdownをHTMLに変換します。自作モジュール内では Python-Markdownというモジュールを使っています。TeX数式については次のnode_svgコンテナにpostで投げてSVGに変換してもらいます。

node_svgコンテナはnode.js環境が乗っており、TeX数式をSVGに変換します。mathjax-nodeモジュールを使っています。

効果

SVG化後のPageSpeedスコア

数式をSVG化した所、PageSpeedスコアは若干改善しました。(まだまだ悪いですが)

また、手元の環境でも、改善前はページのロード時間が

だったのが、SVG化によって

スマホに関しては12倍高速化できました。PageSpeedスコアはまだまだ低いですが、これなら許容範囲です。

課題

  • dockerを使うのではなく、単純なPythonモジュールにできなかったのか
  • コンテナを1つにまとめられるのではないか
  • ホストとの共有ボリュームにPythonのソースを置くのは良くない気がする
  • ホストとの共有ボリュームに.mdファイルを置いて変換するのも良くない
  • 記事中にSVGを含むため、文字数が多くなりすぎてはてなブログのプレビューが重くなって使えなくなった
  • 記事の容量が大きくなりすぎて、記事が投稿できない場合がある

もうちょっときれいな実装がありそうですが、自分のスキル不足で汚い実装となってしまったのが悔やまれます。

似たようなこと

作ってから気づいたけど似たようなことやってる人たくさんいましたね(汗

LaTeX の数式を PNG と SVG に変換するスクリプト - akihiko’s tech note

LaTeXの数式をpngに変換する: dvipngを使う | ゴルディアスの涙目

(あとrender.githubusercontentにURLエンコードしたTeX数式を投げている人もいますけど、勝手にGitHubのサービスを他の用途に使ってもいいのでしょうか?)