nano_exit

基礎的なことこそ、簡単な例が必要だと思うのです。

Seabornをimportするだけでは使えない件について(Mac OSX)

Seabornをpip経由でインストールしたが、importしても変わった感じがせず、決定的だったのがseaborn.pairplotで図が出てこないというエラー。

下記のサイトの下の方に解決法が。
簡単に美しいグラフ描画ができるPythonライブラリSeaborn入門 - MyEnigma

どうやらmatplotlibが古いからupdate (upgrade?) しましょうということでした。

sudo pip install matplotlib -U

これで一応 seaborn.pairplot で図が出るようになりました。
ただし、どうもデフォルトの設定が seaborn.set_style( "white" ) かつ棒グラフの縁の黒線がない状態なので、いろんなサイト様に載っている図と同じにするには多少弄らないといけない模様。

とりあえず、これで色々弄ってみる気にはなった。

MacPortsを使ってMacBook AirにPOV-Rayをインストールしてみた

第一原理計算に必要な原子座標を作るのに便利なpython module "ASE"でPOV-Rayが使われていたので、MacPorts経由でインストールしてみた。

sudo port -install povray

ここまでで、特にエラーメッセージは出ず。
気になるメッセージとしては、pythonバージョンを以下のコマンドで変更しとくように指示するような文が最後に出て来た(若干コマンドはうろ覚えです)。

sudo port select python python2.7
sudo port select python2 python2.7

python3でなくてすみません。
とりあえず言われた通りに変更すると、numpyやらなんやらかんやらが全くimport出来なくなって焦った。
原因は、もともとはpython2.7-appleというバージョンを使っていたのに、違うバージョンにした結果、モジュールのパスが変わってしまったということでした。
どうやってpythonを入れたかもはや覚えていませんが、anacondaで突っ込む前に自分で手で入れたような気もしてきて、その名残が2.7なのだろうかとボンヤリ思っています。
とりあえず、以下のコマンドで元に戻しました。

sudo port select python python2.7-apple
sudo port select python2 python2.7-apple

この状態で、ASEのモジュールをpythonで読んでサンプルコードを動かすと、ちゃんとPOV-Rayを経由して画像が生成されます。

f:id:koideforest:20171111015504p:plain
サンプルコード:
Using the spacegroup subpackage — ASE documentation


povrayのPATHも自動で通っているので、aseを経由して出て来た*.povを引数に動かしてみても画像が生成されました。

povray *.pov

なかなかツヤツヤしていてカッコイイ図が出来るので、POV-Rayそのものをもうちょっと知りたいと思い、以下のサイトを閲覧。
POV-Ray 初心者向けチュートリアル & Tips

なるほど。自分で色々打ち込んで図を作れると。これはワクテカ
GUIが出てくるらしいので、とりあえず引数無しで起動させてみる。

povray

すると返って来たエラーは以下の通り(usernameは適宜置き換えて読んでください)。

poverty: cannot open the user configuration file /Users/username/.povray/3.7/povray.conf: No such file or directory

Problem with option setting
poverty
No input file provided

無いと怒られたファイルのPATHを辿ると、本当にそんなPATHは存在しないので、どこにpovrayの元ファイルが入っているのか"find"で全ファイル検索をかけたら、etcのディレクトリに何かいました。

/opt/local/etc/povray/3.7/

この中にはpovray.confとpovray.iniが含まれていて、中身を読むと、どうやらpovrayはetcのconfファイルとhomeにあるはずのconfファイル二つを読みに行くらしい。
povray.confに当たりをつけて "man povray" でマニュアルを読むと確かにそんなことが書いてあった(最初に読むべきでした。すみません。)。

自分でファイルを作ってconfファイルとiniファイルをそこにコピーして、もう一度起動。

Problem with option setting
poverty
No input file provided

結局、最初のエラーは重要ではなかったらしい。
MacPorts経由で入れると、GUIはついてこない様子。
というか、GUI付きのはunofficialなものしかない。
POV-Ray 3.7.0.x final for mac
なので、MacPortsで入れるとGUI無しのコマンドラインで頑張る方がインストールされるという流れになっていました。

しかし、MacBook Airの容量が割と厳しくなって来ているのでもう一個インストールするのも気が引けるし、かといってASEは問題なく動いているのにuninstallするのもなぁ、、、
とりあえずこれで様子を見てたいと思います。
GUIが無いとやっぱり無理だったら入れてみます。

ではでは

PyQt: トップダウンで作るラーメンタイマー

下記サイト様を参考にラーメンタイマーを作成する。
PyQtではじめるGUIプログラミング
非常に分かり易く説明されていて、個人的にかなり気に入っている。
基本的にはボトムアップ(端っこの部品から作っていく)で記述して行くので、トップダウンを意識して話を作っても良いかと思い、やってみた。細かい話は参照サイト様をお願いしたい。

使うmoduleの宣言

import sys
import PyQt5.QtWidgets as QWs

ラーメンタイマーのウィンドウを表示させる部分。

def main():
  app = QWs.QApplication( sys.argv )

  # Control outside looking
  panel = QWs.QWidget()

  mw = QWs.QMainWindow()
  mw.setWindowTitle( "Ramen Timer" )
  mw.setCentralWidget( panel )
  mw.show()
  app.exec_()

if __name__ == "__main__":
  main()

QWidgetのインスタンス(ここではpanelという名前)をmw.setCentralWidgetに食わせているため、panelを作り込んで行くことで、どんどんラーメンタイマーになっていく。
一応、ここまででもスクリプトは動くが、panelを何も弄っていないため、Ramen Timerと書かれたWindowだけが出てくる。
でも一応動くから安心感はあると思う。最終段階まで動くか動かないかわからないのは精神衛生上良くないので。

とりあえずスタートボタンを追加する。
ボタンを制御するクラスを記述。

class ButtonBoxWidget( QWs.QWidget ):
  def __init__( self, parent=None ):
    QWs.QWidget.__init__( self, parent=None ):
    self.setup_ui()

  def setup_ui( self ):
    self.start_button = QWs.QPushButton( "START", parent=self )

    layout = QWs.QGridLayout()
    layout.addWidget( self.start_button, 0, 0 )

    self.setLayout( layout )

__init__の中身はまだ勉強不足で理解出来ていない。
setup_uiはソースを整理して見易くするために導入されている。そのため__init__内にベタ打ちしても動く。可読性を上げる関数の使い方は参考になる。

panel周辺は以下の様に変更。

  panel = QWs.QWidget()
  panel_layout = QWs.QVBoxLayout()

  button_box_widget = ButtonBoxWidget( parent=panel )
  panel_layout.addWidget( button_box_widget )

  panel.setLayout( panel_layout )
  • アイテム配置用のインスタンス(panel_layout; 今回は後で"箱"を縦に並べて配置するのでQVBoxLayoutを使用)を用意して、そこに先ほど作ったButtonBoxWidgetのインスタンスをLayoutのクラス関数addWidgetで乗せる。
  • ButtonBoxWidgetはparent=panelと繋げておく(この辺の仕組みはまだ理解できていない)。
  • panel_layoutを弄り終わったら、setLayoutでpanelにちゃんと乗せておく。

この時点でスクリプトを起動すると、"START"と書かれたボタンだけが出てくる。他のボタン(例えば"STOP")はstart_buttonと同様にButtonBoxWidgetに記述することで作れる。

したがって、あとは

  1. classを作成・編集してアイテムを作る・作り込む
  2. 作ったclassのインスタンスをpanelに繋げて記述
  3. panel_layoutでインスタンスを突っ込んで、panelに乗せる

を繰り返す。
アイテムを一つ作るごとにスクリプトを動かして確認出来るため、理解を深め易いと思う。

GUIの外見はこれで割と直感的に作れると思う。
あとは実際の動く部分だが、それぞれの部品の動きは各クラスなりpython関数で記述出来ると思う(カウントダウンで数字を減らしていくところは、PyQtのconnectの概念が必要ではあるが)。
それぞれの部品を繋げるのは、Widgetのクラス関数connectで信号を関数に受け渡す(もしくは関数を呼ぶ)ことで実現する。

# bellow mw.show()
button_box_widget.start_button.clicked.connect( countdown_widget.start_countdown )
# above app_exec_()

カウントダウンのクラスについてここでは記述していないが、カウントダウンを始めるクラス関数を自分で作っておき、その関数start_countdownに信号を渡すようにしている。カウントダウンのクラスの詳細は参照サイトを見て頂きたい。
clickedはクラスQPushButtonの持つ関数(クラス?)で、ボタンをクリックした時にどんなアクションをするかを記述出来る。
つまり、
"START"ボタンをクリックするとstart_countdownが呼ばれる
と言う流れである。

一つ一つすぐに確認しながら出来るのはスクリプト言語の強みだと思うので、ちょっとずつ出来上がっていくはやっぱり楽しい。

PyQt: ボタンの解決の順番

下記サイト様を参考に練習中
PyQtではじめるGUIプログラミング

PyQt5 & python2.7 では、QApplication等の主要なmoduleはQtGuiではなく、QtWidgetsに入っている。
ややこしいことに、QWidgetというmoduleも同時に存在している。

#!/usr/bin/env python

import PyQt5.QtCore as QC
import PyQt5.QtGui as QG
import PyGt5.QtWidegets as QWs

def main():
  #app = QG.QApplication( sys.argv )
  #main_window = QG.QMainWindow()
  #hello_button = QG.QPushButton( "Hello World" )
  app = QWs.QApplication( sys.argv )
  main_window = QWs.QMainWindow()
  hello_button = QWs.QPushButton( "Hello World" )
  app.exec_()

if __name__ == "__main__":
  main()

次を足す。

# above the function main()
def on_click():
  print( "Hello World" )

def on_press():
  print( "Have a nice day" )

def on_release():
  print( "Good Night" )

# just bellow "hello_button"
hello_button.clicked.connect( on_click )
hello_button.pressed.connect( on_press )
hello_button.released.connect( on_release )

実行してボタンを押してみると、

press > release > click

の順で解決されることが分かる。

つまり、

press: ボタンを押した瞬間
release: ボタンを離した瞬間
click: press&releaseが解決された後

という感じ

MacにPyQt5をインストール:SIPが入らない。

下記のサイトを参考に、PyQt5をインストールする。
MacとLinuxでPyQtを準備する - Qiita
Qt5.9.2をonline installerでインストール。容量24GBを持って行かれる。MacBook Airには些かキツイが仕様がない。

SIPを入れようとしたところ、"make install"で"Operation not permitted"という文言が出てきてコケる。
調べると、/Systermのdirectoryはsudoでもcp等を受け付けない仕様になっているらしい。
こちらのサイトを参考に解決。
初心者向け MacでOperation not permittedの解決方法 - Qiita

python configure.py --qmake ~/Qt/5.9.2/clang_64/bin/qmake -- sip /System/Library/Frameworks/Python.framework/Version/2.7/bin/sip
"--sip"をつけなかったら、PATHを通すかPATHを指定するか怒られたので、指定することにした。


これで"import PyQt5"でPyQt5のモジュールが呼べるようになった。

スツルム=リウヴィル型微分方程式の表示について

任意の二階の線形微分方程式を次のように書く。

 P(x) \frac{ d^2 f(x) }{ d x^2 } + Q(x) \frac{ d f(x) }{ d x } + R(x) f(x) = 0 (1)

物理でよく出て来る微分方程式(例えばシュレーディンガー方程式等)は大体 P(x)が定数で出て来る。
しかし、物理でよく出て来る特殊関数はスツルム=リウヴィル型の微分方程式の解であり、次の形で表される。

 S(x) \frac{ d^2 f(x) }{ d x^2 } + S'(x) \frac{ d f(x) }{ d x } + T(x) f(x) = 0 (2)

ここで S'(x) = \frac{ d S(x) }{ d x }で、見易くするために使った。
この式を変形すると、

 \frac{ d }{ d x }( S(x) \frac{ d f(x) }{ d x } ) + T(x) f(x) = 0 (3)

と表せる。
特殊関数が満たす微分方程式の形はこちらの表示でよく記述されることが多い。
これが割と不満だった。物理で自然に出てくる微分方程式に特殊関数解が隠れているかを見たいのに、どう考えてもパッと見てチェックするには不便な表示だと思っていたからである。
しかし(2)の表示にしようとすると、(1)からどうやってS(x)をどう作り出すかで見易さが全然変わってしまう。

とモヤモヤしていたら、(1)から(3)へ一般に変形する方法があった。

 P(x) \frac{ d^2 f(x) }{ d x^2 } + Q(x) \frac{ d f(x) }{ d x } + R(x) f(x) = 0
 \frac{ d^2 f(x) }{ d x^2 } + \frac{ Q(x) }{ P(x) } \frac{ d f(x) }{ d x } + \frac{ R(x) }{ P(x) } f(x) = 0

ここに任意の関数 S(x)を全体に掛ける。

 S(x) \frac{ d^2 f(x) }{ d x^2 } + S(x) \frac{ Q(x) }{ P(x) } \frac{ d f(x) }{ d x } + S(x) \frac{ R(x) }{ P(x) } f(x) = 0

スツルム=リウヴィル型にするためには、 S(x) \frac{ Q(x) }{ P(x) } = S'(x)が条件となる。
よって、

 \frac{ S'(x) }{ S(x) } = \frac{ Q(x) }{ P(x) }
 \int dln( S(x) ) = \int dx \frac{ Q(x) }{ P(x) }
 S(x) = exp( \int dx \frac{ Q(x) }{ P(x) } )

とS(x)が求まり、 T(x) = S(x) \frac{ R(x) }{ P(x) } と思えば(3)の表記が得られる。
だから(3)の表記でよく微分方程式が書かれているんだなぁと納得した。

追記(2018/11/21)
(3)の形に変換することをLioville変換と呼び、(3)の形によって微分演算が自己随伴であることが明確になる。
http://user.numazu-ct.ac.jp/~hmatsu/senkou0905.pdf
http://hb3.seikyou.ne.jp/home/E-Yama/SturmLiouville.pdf

モンティ・ホール問題とシュテルン=ゲルラッハの実験

モンティ・ホール問題
モンティ・ホール問題 - Wikipedia
モンティとはテレビの司会者的な存在らしい。
ルールは以下の通り。

(1) 3つのドア (A, B, C) に(景品、ヤギ、ヤギ)がランダムに入っている。
(2) プレーヤーはドアを1つ選ぶ。
(3) モンティは残りのドアのうち1つを必ず開ける。
(4) モンティの開けるドアは、必ずヤギの入っているドアである。
(5) モンティはプレーヤーにドアを選びなおしてよいと必ず言う。
プレーヤーはドアを選び直すべきか?

wikipediaを見る限り、相当盛り上がった問題だった模様。
実際自分も普通に間違えた。
答えは「選び直すべき」であり、景品の当たる確率は2/3である(選び直さなければ1/3)。

ポイントは「司会者の開ける扉がプレーヤーの選択に依存しているということ」と解釈した。
だから条件付き確率を使わなければ計算出来ない問題となる。
プレーヤーが選択する前に、モンティがヤギの扉を開けるルールだったなら単純に当たる確率は1/2で差はなくなる。

この操作の順序によって確率が変わるのは、量子力学のシュテルン=ゲルラッハの実験の応用問題を彷彿とさせる。

(1)電子の集団からz軸プラス方向のものを抜き出す。この時、電子数は半分になる。
(2)その中から更にx軸プラス方向のものを抜き出す。この時、電子数は半分になる。
(3)その中から更にz軸プラス方向のものを抜き出す。
最後に得られる電子数は元の何分の一か?

量子力学におけるスピンの振舞をキチンと説明しないと理解して貰えないだろうが、答えは1/8になる(はず)。
最初にz軸方向のものを抜き出していたんだから、x軸方向に抜き出した後にまたz軸方向で抜き出しても電子数は変わらない、と思ってしまうかも知れないがそうではない。
スピンの検出では検出の軸を決定すると、それに対してプラスかマイナスかしか検出できない。その間の斜め方向とかは無い。斜め方向に向いていた場合、それは検出軸に対して検出されるプラス・マイナスの数の比で表される。誠に不思議な話であるが、自然がそうなっている。
スピンに対して直交した検出軸を用いた場合には、検出軸に対するプラス・マイナス方向のスピンが半々で出てくる。
つまり、x軸プラス方向に向かせてからz軸プラス成分を抜き出そうとすると、また半分になってしまうのである。

量子力学では操作の順番が重要なケースが多いが、量子力学でなくても人間の直感がなかなか及びにくい領域であることがモンティ・ホール問題で明らかになったと思われる。