気になったことを調べた記録

博士号取得後、化学系企業で働いています。物理化学、プログラミング、読書、自転車などが好きです。

量子力学関連の最近の興味

会社にはいってから1年と少々がすぎた。

大学院生の頃にやっていた計算化学からは配属の関係で不幸にも離れてしまったのだが、この間にも有給をとって学会に行ったりと、科学研究への興味は尽きなかった。 サラリーマンというある意味での安全地帯から、いくつかの分野をつまみ食いしてみたこの1年間の興味の変遷を書いておきたい。

化学工学

入った会社では、プラントでの技術部門に配属されたため、まずは化学工学を勉強した。 自分にとって初めて「工学」と名のついた分野の勉強をした気がする。 ここで感じたのは、化学工学はプラントや反応器設計の指針を提供はしてくれるが、それは「答え」ではなく、あくまで「指針」でしかないこと。 実際には、ここで出て来た値を元に、実験したり数値を補正したりしてプラントは作られている。 そのほかにも、法令に縛られていたりなど、化学工学は非常に色々な側面を併せ持っていて、これはこれで非常に奥が深いことがよくわかった(詳しくなったとは言っていない)。

量子力学

僕は大学院生時代、量子化学計算を専門にやっていたが、実際のところは優秀なソフトウェアが存在するおかげで中身の理解が正直なところ非常に危うかった(と思っている)。 そこで、基礎となる量子力学を勉強しなおしてみることにした。

まず読んだのがファインマン量子力学。物理をやる人なら必ず知っている有名な本だ。 今まで原子・分子の電子状態計算しか知らなかった自分にとって、この本の「アンモニア・メーザー」の章にある二状態系の議論など、量子力学が「状態」とそれらの相互作用を定義してやることで本来はもっと豊かな内容を記述できるものであることを今更ながら知った。

次に読んだのが、「新版 量子論の基礎」。 多くの本は量子力学の黎明期の頃の歴史的なところを紹介しながらシュレーディンガー方程式へと行き着く流れだが、現代の量子論の置いている基礎部分に数学的なところを含めてフォーカスしている。 多くの人が同様の感想を持っていると思うが、一通りのことを学んでからこの本を読むと頭の整理になった。

量子コンピュータ(少しだけ)

一時期興味を持って、量子コンピュータ関連の本も読んでみていた。しかし、途中で量子情報アルゴリズムよりも量子もつれの実現方法、あるいは量子現象を見いだすことのできる(量子ビットとなりうる)物質などといった、より物理的な方面に興味がシフトしていき、それ以降は量子情報の勉強はそれほどしていない。

量子工学・開放量子系

最近、量子光学や開放量子系といった分野に興味を持って来ている。

とはいえ、別に量子コンピュータ量子ビットの研究に強く惹かれている、というわけではなく、むしろ環境との相互作用がある系の量子性の維持やデコヒーレンスなどに興味がある。

そのきっかけになったのが、「量子力学で生命の謎を解く」という本。近年、生物系のような非常に込み入ったシステムでも量子現象が見出されることが指摘されている。一般的に、固体物理などの分野で出てくる物質は、非常に高いエネルギーをかけて作られた結晶性の高い均一な物質である。しかし、その真反対に位置するような生体分子に置いても量子的重ね合わせなどといった現象が発見されたのは非常に興味深い。ここから、自分の現在の興味が湧いたと思っている。

こうして、現在は環境との相互作用やそれに伴う量子のデコヒーレンスといった現象の理解にとても興味を持って見ている。

こうしてみると、学問の世界も広いなぁと(他人事みたいだけど)改めて思う。 僕は理論を勉強して、計算機でモデルを組んで注目する系の性質を弄って遊んで見るというのが好きなのだが、これらの理論がどのような系で実際に見出されるか、というのは然るべき観測装置を以って実験をしてみないとわからない。 今の興味はこの境界のようなところにあって、興味深く今後も見ていきたいと思う。

Strength Finder2.0をやってみた話

巷で有名なこの本、Strength Finder(邦題:さあ、才能(じぶん)に目覚めよう 新版 ストレングス・ファインダー2.0)をご存知だろうか。

この本の存在自体は知っていたのだが、今更ながら試してみた次第である。

この本を買うと1回限り有効のアクセスコードがついてきて、それを利用してテストを受ける。このテストは20-30分程度かかるもので、受けていると少々疲れてもくるのだが、回答後に表示されるレポートで「確かに当たってる気がするわ」と思わずにはいられない自分のTop 5の資質と説明、その資質を伸ばすための今後の行動の提案、同じ資質を持っている人の成功例をみることができる。

本に書いてある内容は、(厚みの大部分は)これらのレポートをすべての資質に関して網羅しただけなので、実際にはアクセスコードにのみお金を払っているような感じである。

 さて、これを自分がやってみた結果、自分のトップ5の資質は、

  1. 学習欲
  2. 内省
  3. 達成欲
  4. 分析思考
  5. 親密性

ということだった。当たっているのか?? 思い当たる点はもちろんあるのだが、自分一人で考えるとこういうのは散乱しがちなので、こうやって客観的指標でリストされると大変わかりやすい。 なんだか色々言い当てられている気がする!

 昔の版(バージョン1.0)では、どうもトップの資質のみが得られたらしいのだが(詳細不明)、バージョン2.0は同じ資質をもつ人たちの成功例や行動アドバイスを受け取れる点が進化したことらしい。そういうわけで、自分へ向けられた行動アドバイスをそれぞれ簡単に表にしてみた。

資質 説明 強みの洞察 やること
学習欲 学習意欲が旺盛で、常に向上を望んでいる。結果よりも学習すること自体に意義を見出す 本能的に学術研究にのめり込むことがある。
特定の概念を習得したり、重要な情報を記憶することに熱心に取り組んだり、特定のコースの必修科目を終えたりするまで休まないことがある
学習の進捗度を記録すること。
変化を起こす人になること。
できる限り、技術や規則が常に変化する分野にキャリアを変更する。
内省 頭脳活動に多くの時間を費やす。自分の頭で考えるのが好きで、知的な議論を好む。 生まれながらにして、現在の出来事に注意を払う。 考えたことを日記や日誌に箇条書きで書き留めておく。
「偉大な思想家」と考える人たちとは意識的に関係を築くこと。(←なんだか壮大だ。。。w)
書くための時間を作る。
関心を持つものと同じ話題を語りたいと思っている人を見つける。
達成欲 並外れたスタミナを持ち、旺盛に仕事に取り組む。多忙で生産的であることに大きな満足感を得る。 多くの場合、物事がどのように機能するか解明することに熱心に取り組む。さまざまな問題、プロセス、メカニズムを何時間も研究することを楽しいと感じる。 好きなだけ忙しく働けて、生産性を測るよう奨励される仕事を選ぶ。
専門分野に関する学会や講義に出席したり資格を取得することで学ぶことを続ける。
よく働く人をパートナーにすること(←!)
分析思考 物事の理由と原因を追求する。状況に影響を与える可能性のあるすべての要素を考慮にいれる能力を備えている 数値データの解釈である程度の手際の良さを発揮する データを分析したり、規則性を発見したり、アイデアを整理することに注意をはらう仕事を選ぶこと。
信頼できる情報源(本、ウェブサイト、刊行物など)を選定しておく
蓄積し分析した情報が必ず使われ、実行されるようにする。
親密性 他人との緊密な関係をたのしむ。目標達成のために友人と努力することから、大きな満足感を得る。 生まれながらにして、わかりにくい考えや仕組み、プログラム、プロセスなどの無駄をそぎ落として基本的な要素を取り出すことに成功するといい気分になれる
自分自身で明確な目標を設定している人を手助けしたいと思う
友情が奨励される仕事を選ぶこと。形式的すぎる環境ではうまくやれない。
どんなに忙しくても友人とは連絡をとること

これをみると、資質とその強みの洞察が一度聞いただけではリンクしないものも多少ある気がするのだけど(例えば、親密性のところで、「わかりにくい仕組みなどの基本的要素を取り出すことに喜びを感じる」など)、同様の性質の人に共通してるんでしょうな。
 ちなみに、レポートの内容はすべて下記のまとめサイトに書かれている。

xn--bckg8a9ab8bxc5fpjscf3i.com

 なぜこんなことをわざわざ記事に書いたかというと、2種類の強みのところで考えなどを書き留めることを推奨されていたため。また、その他にも、自分はあまりモノ(product)を作る方向には向いていないのかもとこれまでも薄々感じたりしていたのだが、それも上のレポートをみるとなんとなく符号する気がしてきた。
 これから何をすることになるかはわからないが、転職諸々考える時はこのあたりの自分の性質も鑑みながら検討したり、あるいは趣味でも色々とやっていこうと思った次第である。

大昔のgccのプリプロセッサに関する、極めてどうでもよい話

先日、酒を飲みながらgccだかなんだかのコンパイラの話をしていたときに、ふと、「そういえば昔のgccプリプロセッサ#pragmaディレクティブを見つけると、コンパイルを中止してゲームを起動するとかいうのがあったよな」と思い出した。 この元ネタは、もう絶版だけど、「エキスパートCプログラミング」という本に書いてある。

エキスパートCプログラミング―知られざるCの深層 (Ascii books)

エキスパートCプログラミング―知られざるCの深層 (Ascii books)

C/C++において、#pragmaは、ヘッダの二重インクルードを防止するために、伝統的な

    #ifndef GUARD
    #define GUARD
    ...
    #endif

を使用したインクルードガードに変わって#pragma once のように用いられることが多い。しかし、pragmaに続くキーワードやその動作は下記のページにもあるように、処理系ごとに定義が委ねられている。

C言語/前処理指令 - Wikibooks

当時のgccはどうも#pragmaいけ好かないものとしていたようで、「処理系ごとに決められた動作」として、ゲームを起動するというようなことをやっていたらしい。

せっかくなので、gccの古いソースコードを掘り返してみる。 アーカイブへの直リンクは

http://ftp.tsukuba.wide.ad.jp/software/gcc/old-releases/gcc-1/

さて、まずは一番古そうなのをということで、verion 0.9 (gcc-0.9.tar.bz2, 1987/03/22リリース)を覗いてみる。 このなかの、cccp.cというファイルを見てみると、2401行目付近に、

/*
 * the behavior of the #pragma directive is implementation defined.
 * this implementation defines it as follows.
 */
do_pragma ()
{
  close (0);
  if (open ("/dev/tty", O_RDONLY) != 0)
    goto nope;
  close (1);
  if (open ("/dev/tty", O_WRONLY) != 1)
    goto nope;
  execl ("/usr/games/hack", "#pragma", 0);
  execl ("/usr/games/rogue", "#pragma", 0);
  execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
  execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
  fatal ("You are in a maze of twisty compiler features, all different");
}

というように、このころのコードには確かにゲームを起動するコードが仕組まれている。ちなみに、私はhackもrogueも名前だけは知っていたが、起動して遊んだことはないので何するゲームなのかよく知らない*1。 なるほどexeclはそのプロセスをそのまま呼び出すコマンドで置き換えるから、より新しいものから起動を試してみて、見つからなかったらrogueというように順々に探していくわけだ。 ちなみに、コンパイルができなかったために、本当にpragmaを見つけるとゲームが起動するのか、手元で確かめてはいない。というのも、do_pragma()という関数自体が、関数ポインタを介して呼ばれているようで、必ず呼ばれるものか、いまいち確信は持てていないためだ。

つぎに、gcc-1.21(gcc-1.21.tar.bz2, 1988/05/01リリース)を見てみる。 すると、同じくcccp.cの2993行目付近

#if 0
/* This was a fun hack, but #pragma seems to start to be useful.
   By failing to recognize it, we pass it through unchanged to cc1.  */

/*
 * the behavior of the #pragma directive is implementation defined.
 * this implementation defines it as follows.
 */
do_pragma ()
{
  close (0);
  if (open ("/dev/tty", O_RDONLY) != 0)
    goto nope;
  close (1);
  if (open ("/dev/tty", O_WRONLY) != 1)
    goto nope;
  execl ("/usr/games/hack", "#pragma", 0);
  execl ("/usr/games/rogue", "#pragma", 0);
  execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
  execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
  fatal ("You are in a maze of twisty compiler features, all different");
}
#endif

というように、コメントアウトされてしまっている。しかも「なんだか使い道が見えてきた(意訳)」という言い訳つきである。上記のwikibooksによると、「処理系が認識できないプラグマは無視する」と書いてあるが、この段階ではコメントにもあるように、プリプロセッサでは無視しているようだ。

エキスパートCプログラミングという本自体、1996年に出版されていることを考えると、この本が「昔」というのだから「昔のさらに昔」ということで本当に初期の一瞬だけの話だけだったようだ。ちなみに、私は1990年生まれなので、生まれる前にはもうpragmaは「ちゃんと使われていた」ことを今更知った次第である。

なお、gcc-0.9のビルド周辺に関しては、下記のページでビルドの試行錯誤などがされている。

https://virtuallyfun.superglobalmegacorp.com/2016/12/01/building-using-gcc-0-90-aka-first-public-version/virtuallyfun.superglobalmegacorp.com

終わり

DJに入門した話

実は3年くらい前から、DJに憧れていた。 きっかけは、知り合いのエンジニアの方が、いつぞやのプログラミング言語のカンファレンスの懇親会でDJをやっているのを見たから。その後、今の研究室に移ってからはなんとプロのDJがいて、ちょっと教えてもらうにも非常に良い環境でもあるのだが、 なかなかお金もかかるもので結局やらないままだった。(ずっと「いつか始めたいんですけどね。。。」と言うだけだった)

そうこうすること3年弱、この前我が研究室のDJの方が、こいつ↓を持って来て、プレイするところを見せてくれた。

jp.monstergodj.com

そもそも自分がなかなか始められなかったのは、DJを始める上での初期投資となる

  • タンテ×2(もしくはCD×2)

  • ミキサー

  • ヘッドホン

のコストが自分の経済力ではやれなかったからなのだけど、今の時代(ここ数年?)こんな小さなマシンであんなカッコいいことが出来るとかマジでヤバい。鞄からさっと取り出していきなりバンバン音を操りまくって。。。ていうのがカッチョよすぎる。
就職活動でなんとなく落ち着かない生活も終わったということで、迷わず再入荷のタイミングで買いました。

こんな感じ。やばい。かっこいい。 f:id:salondunord:20170711002759j:plain

今はまだ操作の仕方も全然感覚的でなくて(まだどのボタンを押したらどうなるのかもよくわかってない)、曲を繋ぐとかもってのほかなのだけど、それでも自分がPCに入れていた曲がちょっとボタンを押したりつまみをひねるだけで音が変わったりするのは本当に面白い。 それ以来、毎晩帰宅してからちょこちょこ弄って遊んでるんだけど、しっかり練習していつか僕も何かの懇親会とか結婚式の二次会とかそういうところで回させてもらえるようになりたいと思う。

以上、やめない為の決意表明でした。

MONSTER GODJ Portable, Stand-Alone DJ System and Production Studio【正規代理店品】

MONSTER GODJ Portable, Stand-Alone DJ System and Production Studio【正規代理店品】

量子化学計算のプログラムを自作してみた

普段、量子化学の計算を行う際は、GaussianやGAMESS他のソフトが用いられることが殆どで、自分でコードを書くのは計算手法の研究をされている一部の方に限られるのではないかと思います。

近年では、B3LYP汎関数の使用を始めとする、密度汎関数理論(Density Functional Theory; DFT)が用いられるケースが殆どですが、それに先立って確立された手法として、Hartree Fock法があります。 Hartree Fock (HF)法は、計算結果のエネルギーの見積もりの不正確さ*1から、今ではこの手法が単体で使用される場面は多くはありません。 しかし、近似の仕方が明確なため*2量子化学の基礎として多くの方が一度は勉強される理論かと思います。

私も、数年前に教科書でHFの理論を勉強してから、一度は自分でコードを書いておきたいという気持ちがずっとあったのですが、毎回途中やめになっており、このたび漸くそのminimalな実装をC++で書ききりました。実際に書いてみると、式を読んで分かった気になっていたものの、実際の理解は曖昧だったりといったことがよくわかりました。

コードは、下記のリポジトリにおいていますので、気になる方、これから同じことを勉強しようと言う方はどうぞ。

github.com

感想としては、結構大変でした。Gaussianなどの開発チームだったり、もしくは日々新たな計算手法を開発されている方たちが神に見えてきます。 以下に気づき、感想、苦労した点を列挙します。

1. Gauss型の短縮基底関数の正規化

これは、自分で書いてみるまで気がつかなかったことです。 (といっても書き始めたのが2年くらいは前なので、その頃に気がついたのですが。。。) 例えば、STO-3Gという最も基本的な基底関数系で、水素の1S軌道は、軌道指数(Orbital exponent, よくαと書かれます)と計数を強調して、

 H_{1s} (r) = 0.44635 g(-0.168856) + 0.535328 g(-0.623913) + 0.154329 g(-3.42525)

という感じでよく表されます。ただ、これを  g(\alpha) = \exp(-\alpha r^{2}) と考えて素直に計算すると、一番簡単なはずの重なり積分から数字が合いません。

実際には、(後で気づけば当たり前のことではあるのですが...)それぞれのプリミティブガウス関数に、それぞれを全空間で積分した際の値が1になるように、規格化因子がかけられています。また、さらに、それらを重ね合わせた関数(短縮ガウス関数)にも、規格化因子が掛けられます。したがって、より正しい表記は、

 H_{1s} (r) = \frac{1}{0.999999 } (0.44635 \frac{\exp(-0.168856 r^{2})}{0.187736} + 0.535328 \frac{\exp(-0.623913 r^{2})}{0.500326} + 0.154329\frac{\exp(-3.42525  r^{2})}{1.79444} )

となります。これらの規格化因子は、プリミティブガウス関数のそれぞれについてまず求め、その後、短縮ガウス関数について求める必要があります。なお、p軌道以上の角運動量を持つ軌道には、 x^{l}y^{m}z^{n}という因子がかかるので、これも考慮に入れる必要があります。

2.積分の実装

積分は、1966年に竹田、藤永、大旗の3名が書いた論文を参考にしました。これの実装がとにかく難しかったです。慣れれば、重なり積分と、運動エネルギー積分はまだなんとかなります。難しいのは、核引力積分(Nuclear Attraction Integral)と電子間反発(4中心)積分の部分です。

これらは、とにかく展開方法もなかなか理解できませんし、非常に入れ子の深いループになってしまいます。

現状は上記の論文をそのまま参考にしており、STO-3G基底での水素分子やHeH+イオン程度は一瞬で計算は終わりますが、試しにp軌道を分極関数として追加してみると、一気に遅くなりました。

近年のGaussianを始めとする量子化学計算プログラムは、PRISMアルゴリズムなど、積分ごとに20種類くらいのパスを使い分けるような非常に複雑な実装*3がなされているそうですが、その重要性がよーく分かりました。 今後は、できればDKRの積分方法や、Obara-Saikaの展開公式なども実装してみたいと思います(できれば、です。2電子積分の展開など、まだ全然理解できていません。)

3. 何を使って行列演算を行うか

王道はBLASなどのライブラリを使うことなのだろうと思いますが、恥ずかしながら私は他のプログラムからリンクさせる為にコンパイルした程度の経験しかありませんでした。

以前にnumpyを使って今回と同じようなものを書こうとしたことがありました*4ので、今回は比較的それと似たような感覚で使えそうなEigenというテンプレートライブラリを使用しました。

おそらくBLASなどのような高度なチューニングは難しいでしょうが、今回のような目的には非常に使い勝手が良かったと思います。

今後

現状はHartree FockのRHF計算のみ実装しましたので、今後はUHF計算をまずは実装したいと思います。 あとは、スパコンが使える今のうちに、少しくらいMPIチューニングなどで遊んでみるのも良いかもしれません。 その次は、DFTか微分計算ではありますが、おそらくUHFを書いてみるころには学生生活が終了している気がします...苦笑

2017.07.15 追記

UHFの計算はSzaboの本を見ながらすぐにかけてしまいました。 今はDFTを実装するべくいろいろ調べていますが、交換・相関ポテンシャルの空間積分のためのグリッド生成がなかなか難しいです。またここにメモをする予定です。

追記その2 Qiitaにメモしました。まだ積分は書いていなくて、ハードコーディングしてます。 qiita.com

新しい量子化学―電子構造の理論入門〈上〉

新しい量子化学―電子構造の理論入門〈上〉

密度汎関数法の基礎 (KS物理専門書)

密度汎関数法の基礎 (KS物理専門書)

*1:電子相関(≒電子同士の避け合いの効果)を考慮しない

*2:基底関数以外に経験的なパラメータを含めていない

*3:すいません、嘘言っているかも。全然この辺りの詳細は知りません

*4:どうしても2電子積分の値がズレてしまい放置...

VASPで計算したバンド構造の可視化のためのスクリプト

固体のバンド構造計算をこれまでは主にQuantum Espressoというフリーのコードを使って行っていたのですが、最近、少々vaspを利用した計算を行っていました。

vaspでバンド構造を計算すると、EIGENVALというファイルが作成されて、そこに各k点での固有値が記録されます。 このファイルを何らかのツールを使って可視化する必要があるわけですが、検索してみると主に出てくるのはp4vaspというプログラムを利用する、というもののようです。

しかし、p4vaspはなんだかバンド図の見た目がイケてない上に、磁性を考慮した場合にどうもupとdownのスピンのバンドを別々にカラーリングする方法がわからず、バンド図の可視化には使いづらいように思えました。 そこで、gnuplotによる可視化向けにEIGENVALSファイルを読み込んで整形するスクリプトRubyで作成しました。

github.com

本当はここに結果を載せたいのですが、一応vaspはライセンスの縛りがあるので、ここに結果のグラフを載せるのは避けておきます。

使い方は、EIGENVALSのあるディレクトリで、

ruby read_eigenvals.rb -n (各kpathの点の数)

とするだけです。オプションを適当に渡せば、スピンを考慮した計算結果のファイルや、gnuplot用のスクリプトも一緒に作成します。

理論化学の本を紹介していく(電子軌道の概念)

量子化学の一番初めは、とりあえず波動関数とは何ぞや?を抑えることだとすると、その後で来るのは、今度は軌道の概念を知ることだと思っています。 私は軌道のことは、友田修司先生の本で勉強をしました。

基礎量子化学―軌道概念で化学を考える

基礎量子化学―軌道概念で化学を考える

この本で使っている計算法は拡張ヒュッケル法などの現代の量子化学コミュニティではあまり使われなくなってしまった古い計算方法です。

しかし、軌道の概念をきちんと理解するためには、むしろこのような手法の方が変に原子軌道の混成を考えなくてよくなるため、定性的な理解には良いと思います。

この本はそれほど大きくない分子を用いて、

  • フロンティア軌道

  • 配位子場分裂・結晶場分裂(金属に配位したイオンなどにおいてみられる3d軌道の分裂)

などを議論しており、これらの概念を掴むには良いと思っています(ただし、すごく深いわけでもないと思います)。

また、溶解エネルギーなどの熱力学的な量に関する解説もある程度されており、数表としても私は使っています(ただし、そんなに量は無いので、本当に必要な時は化学便覧を見るのが良いです)。

私は指導教員によく言われるのは、「計算機で計算する数値データは、コンピュータとか計算手法が発展するので10年たったら役にたたないが、軌道を見た時の定性的な傾向(たとえば、フロンティア軌道は分子のどのあたりに局在しているか、など)は別の量子力学的効果を入れたりしない限り変わることは無いので、それをきちんと把握すること」ということです。

この本はその感覚をつかむために最適なのではないかと思っています。

ちなみに、軌道の概念をさらによく知るためには、洋書ですが、

Orbital Interactions in Chemistry

Orbital Interactions in Chemistry

かと思います。