Python Corner

(Python-2.5 on Leopard)

目次


能書き・環境整備

元の "Python Corner" はもう大部古くなってしまったようだ。 何より、現在 (2008-06-07) 主に使っている環境は、Leopard (MacOS X 10.5.3) だったりする……。 なので、すっかり新しくする事にした。

とりあえず、数値計算・プロットを中心に、Leopard 上の環境整備について述べる事にし、GPIB 他のトピックは追々書き足していくつもり。

Leopard に Python をインストールするには色々な手が有るようで、

  1. Leopard についてくるのをそのまま使う。何と、Leopard 10.5.2 には、Python-2.5.1 がついて来た。(/usr/bin/python2.5)

  2. MacPort でインストールする。これも 2.5.1。 (/opt/local/bin/python2.5)

  3. Python.org から、MacPython (python-2.5.2-macosx.dmg) をダウンロードしてインストール。 (/Library/Frameworks/Python.framework/Versions/2.5/bin/python2.5)

  4. source からコンパイル。 (/usr/local/bin/python2.5)

等々(いろいろ有ってちょっと「嬉しい悲鳴」状態)。Python 通(追っかけオタク)としては、ここは迷わず 4. でしょう、と言いたいところだが、 実は 3. に落ち着いている。1. と 2. は、アップデートが遅れるだろう、との見込み通り、今日現在 (2008-06-07) どちらもまだ 2.5.1 のまま。3. は、4. をインストールした後、IDLE 他を試そうとインストールしてみたのだった。 最初はその「やたら深いインストールディレクトリ」が心配だったが、 /usr/local/bin に link を張ってくれるし、 その Python が、各モジュールを適切なディレクトリにインストールしてくれるので、 shell から「Python を起動」「モジュールをインストール」 いずれの場合にも、source からコンパイルしたものと同様に使える。 すなわち、例えば
$ sudo python setup.py install 
で、所定の(深〜い:-) 位置にインストールしてくれる。

しかし、3. の本来の目玉だった IDLE を今はあまり使っていない。 カラフルで楽しかったのだが、AquaSKK で日本語が入力できない、実行がやたら遅い、等に恐れをなして、 慣れるところまで行かないうちに使うのを止めてしまった。 しかし、上述のように、command line からの使い勝手は悪くないので、 4. に戻らず、3. を使い続ける事にした。

Emacs 上の py-shell も、一時は嵌っていろいろ試したが、しばらく離れていると、凝った使い方 ("py-execute-region" と py-shell を連携させる等)はすぐ忘れて、いつの間にか、Terminal.app から Python を起動して、という使い方に戻ってしまう。 これ(Python on Terminal.app + Zsh)も悪くないけど、py-shell での実行はもっと便利そうなので、しばらくは強いて使って慣れてみようと思っている。

そのためには、Emacs に附属の python.el ではなく、python-mode.el を使った方が具合が良いようだ(単にこちらに慣れている、というだけの事かも。) source forge から、 python-mode-1.0.tar.gz を取ってきて、これを /usr/local/share/emacs/site-lisp の下へ展開する。 また、~/.emacs に下の行を追加。

(autoload 'python-mode "python-mode" "Python editing mode." t)

Numpy/gnuplot-py

Python の数値計算モジュールは、numpy で落ち着いたらしい。御同慶の至り。 但し、少し前まで Gnuplot-py が numpy には対応してくれていず、また、Python の with が、-2.6 から予約語になるとかで、それに関する warning が出まくる状態となり、 対応にかなり手間暇がかかった。 本当はその顛末を書こうと思っていたのだが、gnuplot-py-1.8 が出たおかげで、私の四苦八苦は殆んど解消できた。
numpy:
-1.1.0 から .dmg パッケージが入手可能になっている。今では Python も .dmg からなので、迷わずそのパッケージ (numpy-1.1.0-py2.5-macosx10.5.dmg) を使う事にした。 が、 numpy.test() が通らない……
======================================================================
FAIL: check_testUfuncRegression (numpy.core.tests.test_ma.TestUfuncs)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5\
    /site-packages/numpy/core/tests/test_ma.py", line 692, in \
    check_testUfuncRegression self.failUnless(eqmask(ur.mask, mr.mask))
AssertionError

----------------------------------------------------------------------
Ran 1319 tests in 1.495s

FAILED (failures=1)
<unittest._TextTestResult run=1319 errors=0 failures=1> 
source からコンパイルしても同じ Failure となる。 後述のように、ちょっと四苦八苦したが、-1.0.4 に無い試験項目で落ちているので、 それより信頼性が低いと訳ではないと見て、今はまた .dmg 版の -1.1.0 に戻した。(ちなみに、Linux では Python-2.5.2 と numpy-1.1.0 の組合せで自己テストが通る……。)

gnuplot-py:
gnuplot-py-1.8 をソースからインストールした。 上述したように、MacPython でもソースから setup.py install で問題なくインストールできる。

Gplot:
gnuplot-py の with が、Python の with と当っているので、私は gnuplot-py のその部分を wit に置き換えて使っていたが、新版(-1.8)では、初めから with_ に置き換えてくれている。それに応じて、手製の Gplot.py の wit with_ に置き換えた。この時だけは、モジュールが /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/ に有る事(もしくは、PYTHONPATH が通っているディレクトリに有る事)を意識する必要がある。ちなみに、 Gplot.py はこの他にもかなり改善されて(変って)いる。
  • Plot1/plot2 のかわりに plot のみを使う。 引数の与え方で、どのような plot をするかが決まる。
    1. g.plot(x, y): (x, y) を実線でプロット

    2. g.plot(x, y, y1): (x, y) を実線で、(x, y1) を点でプロット

    3. g.plot(x, y, y1, x1): (x, y) を実線で、(x1, y1) を点でプロット

  • default の gnuplot script を "default.gps" というファイルから読み込む。(無ければ何もしない。)

  • X11 でも aqua でも動く(筈)。

3. は、理論値を (x, y) で、測定点を (x1, y1) でプロットするという一番ありそうなケースを想定している。
Numpy-1.1.0 の自己テスト失敗を何とかしようと四苦八苦しているうちに、 Scipy Superpackというものに行きあたった。SVN 版の numpy のみならず、 Matplotlib や iPython もインストールしてくれるという優れものらしいが、 残念ならが、自己テスト失敗は直っていない……。しかも、元に戻そうとしても numpy 他を上書きしただけでは ImportError が出るようになってしまった……。 仕方なく上記の .../Versions/2.5/lib/... の 2.5 を rename して、また MacPython(.dmg 版)から入れなおした。 これは勿論「オーバーキル」だろうけど、結局近道だったような気もする。

手始めに

実際に Python を立ちあげて、sample session をやってみる。

 fukuda@quadra:~% python
 Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) 
 [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
 Type "help", "copyright", "credits" or "license" for more information.
 # numpy モジュールをインポート
 >>> from numpy import *    
 # numpy の fft モジュールから関数 fft をインポート
 (モジュール名が FFT から fft になって何だか解り難い)
 >>> from numpy.fft import fft
 # Gnuplot のラッパ Gplot をインポート
 >>> import Gplot as G
 # 時間軸と周波数軸の定義     
 >>> t = arange(0.0, 4.0, 1.0/16)  # 0 から 4 まで 1/16 きざみ 
 >>> f = arange(0.0, 16.0, 1.0/4.0) 
 # サンプルとして v(t) = cos(2πfot) + 0.5cos(2π2fot) を定義する。
 >>> v = cos(2.0*pi*1.5*t) + 0.5*cos(2.0*pi*3.0*t)
 # これをプロットしてみる。
 >>> g = G.Gplot()
 >>> g.plot(t, v)
 # このコマンドでこのようなグラフが pop up する筈 (click で拡大画像)。
[COS curve]
 # この関数 v(t) の Fourier 変換 V(f) を求める。
 >>> V = fft(v)
 # この V(f) を plot する。(V(f) は複素数だから、絶対値に直して表示)
 >>> g.plot(f, abs(V))
[FFT]
FFT の結果が、0 -> fmax -> fmin -> 0 の順番で出力されるのでちょっと解り難いが、
 # 負の周波数にシフトした sf を作り
 >>> sf = f[:]
 >>> sf[32:] = arange(-8.0, 0, 1.0/4.0)
 # これに対して plot してみると ±1.5 Hz と、±3.0 Hz のところにちゃんと
 # ピークが来ているのが解る。
 >>> g.plot(sf, abs(V))
[FFT shifted]

以上で、途中の関数のグラフで確認しながら、サンプルの関数を定義し、 それを FFT してみた訳だが、驚く程簡単だった。 私はちょっと「感動もの」だと思う。

しかし私には、 この「簡便」という事よりスクリプトがとても「直観的」 になる事の方が嬉しい。例えば、

 v = cos(2.0*pi*1.5*t)
と定義すれば、それ以降、 普通の数式を扱うようにこのオブジェクトを扱える(代入する、 プロットする等)。まあ、v を v(t) と書けたり、cos(2π1.5t) なんて書けたらもっと嬉しいが、それは欲張りすぎというもの。

これは、numpy というモジュール内の数学関数が、 「配列 (array) を引数に取り、また配列を戻り値として返す」 という設計になっている事のおかげである。Arange で定義されている t や f は実際は一次元配列になっている訳。 また、それを引数として計算される v も実は一次元配列。 またこれから、V = fft(v) というたった一行で、その Fourier 変換 V が得られたのだった。

この事の効果は絶大で、論文を読む時、数式を visiualize しながら… とか、数式の導出を、シミュレーションで確かめながら(邪道か?) などという場合に、とても見通しが良くなる事は請合い。


112/1,050,010
Taka Fukuda
Last modified: Sun Jun 29 17:33:18 PDT 2008