Fri Mar 01 2019

日記 - vim, terminal, ipython

言ってしまえばこのようなことがしたかった:

試み1: cympfh/htty

これはサーバとして動いてREPLを子プロセスに持つ. REPLのstdioをhttpでやる.

良さ. エディタと独立して動くので, vim はいつでも閉じていいし, また好きなタイミングでいくつでもアタッチできる. エディタを使わなくても curl でコマンドを送っても良い.

良くなさ. セキュリティガン無視. バグってる (物によってはstdioが利用できない. ipython は使えるけど python は使えなかった). 複数REPLを起動したらいちいちどこに送るかをポートで管理する必要がある. エディタで例えば、「コードを選択してショートカットキーを押したらバッファを送信する」ことをしたいが、どこに送るかを選ぶ機構が必要になる.

試み2 :terminal

vim8.1から (正確には vim8.0 からだが非推奨) :terminal コマンドが生えて、ターミナルを起動するバッファが開く. デフォルトではシェルが起動し、:terminal ipython などとして自由なREPLが起動できる. そのままでは単にvimの中にターミナルが開いたくらいで、GNU terminal や tmux くらいの良さしかない.

vim のバッファの中の文字列をターミナルに送れたら便利だ.

https://stackoverflow.com/questions/49318522/send-buffer-to-a-running-terminal-window-in-vim-8

にその方法の例が示してあった. というわけで私も .vimrc に以下を追加した:

https://github.com/cympfh/dots/commit/98fa73bbaa67558cfe586980318d338168658526

良さ. バグってない (バグってもコミュニティにサポートされる). 例えばタブごとに :terminal すれば複数REPLを立ち上げておいて, それでバッファを送信する先も, 「今見えてるターミナル」 になるので分かりやすい. いちいちショートカットキーを変えなくてもいいし.

良くなさ. 立ち上げた vim はRPELを落としたくない限り落とせない. またそのvimに入らないとバッファは送れない.

メモ

ipython は偉くて、エディタがやるように勝手にインデントの挿入をしてくれる (例えば def f(): の次の行は必ずインデントされるはずだからインデントしてくれる). なので例えばvimから

def f():
    pass

というバッファを送ると、ipythonがしてくれるインデントの後ろにさらにインデントを送ることになる. if 文など書くとたぶんこじれるので :terminal ipython --no-autoindent で起動しておくとこれが防げる.

日記 - アインシュタインの規約

というものがある.

2つの長さの等しい有限の数列 \(\{a^1, a^2, \ldots, a^n\}\) \(\{b_1, b_2, \ldots, b_n\}\), があるとする. ここで \(a^i\)\(i\)\(b_i\)\(i\) と同様に添え字であって, べき乗などではない (添字が上にあるか下にあるかは重要). これらについて \[\sum_i a^i b_i\] という値に興味があり, この式が頻出するとする. こういう場合に, \(\sum\) の記号を省略して, \[a^i b_i\] と書く. これをアインシュタインの規約という.

約束としては, (自由変数でもないのに) 上と下にペアで添字が出てきたら, それについて和を取っているものとして読む. またペアは和について分配する. つまり \[a_i (x^i + z^i)\]\[a_i x^i + a_i z^i\] のこと. さらにこれは項ごとに和を取ってるので項ごとに \(i\) という添字をリネームしてしまっても構わないはずだ. \[a_j x^j + a_k z^k\] というふうに (ここに \(j,k\) は他に出現しない, しても干渉してないとする).

ただし添字がちょうどペアになっていなかったらおかしい. 例えば \[a_i x^i z^i\] はおかしい (このようなものが出てこない計算をする).

この記法が良いのは, 単純に \(\sum\) を書かない分紙面が省略できることもあるが, それ以上に, また添字に関するバグが早めに検知できることがある. 上に書いたような \(a_i x^i z^i\) とか \(x^i z^i\) とかが出てきたらおかしい. あるいは自由変数でもないのに \(i\) が一回だけしか登場してなかったらもちろんおかしい.

実は上付きの添字は行ベクトルで, 下付きの添字は列ベクトルを表してる, と考えている (行と列はどっちでもよくて本質ではないけど). つまり \(i=1,2,\ldots,n\) だとして \(a^i\) とは \[\left[ a^1, a^2, \ldots, a^n \right]\] のことで \(b_i\) とは \[\left[\begin{array}{c} b_1\\ b_2 \\ \vdots\\ b_n \end{array}\right]\] のこと. そして \(a^i b_i\) とはこの2つのベクトルの掛け算 (つまり内積) のこと.

話はもっと一般的で, 添字が2つなら行列と考えて差し支えない. 例えば \[a^i x_i^j b_j\]\[\left[ a^1, a^2, \ldots, a^n \right] \left[\begin{array}{ccc} x^1_1 & \ldots & x^1_n \\ \vdots & (x^i_j) & \vdots \\ x^n_1 & \ldots & x^n_n \end{array}\right] \left[\begin{array}{c} b_1\\ b_2\\ \vdots\\ b_n \end{array}\right]\] を表している.

要は「各indexについて成り立っている等式」を頭の中で行列の演算に書き換えている. 添字はより増えても構わない. \[x^i z^j \xi^k \Gamma_{ijk}^\ell\] このような \(\Gamma\) はもはや行列では表現できなくて, テンソルと呼ばれる. 特に上に添字が 1 つあって下に添え字が 3 つあるので \((1,3)\)-型テンソルと呼ばれる.