Python Corner
(Python-2.5 on Leopard)
目次
能書き・環境整備
元の "Python Corner" はもう大部古くなってしまったようだ。 何より、現在 (2008-06-07) 主に使っている環境は、Leopard (MacOS X 10.5.3) だったりする……。 なので、すっかり新しくする事にした。
とりあえず、数値計算・プロットを中心に、Leopard 上の環境整備について述べる事にし、GPIB 他のトピックは追々書き足していくつもり。
Leopard に Python をインストールするには色々な手が有るようで、
- Leopard についてくるのをそのまま使う。何と、Leopard 10.5.2
には、Python-2.5.1 がついて来た。(
/usr/bin/python2.5
) - MacPort でインストールする。これも 2.5.1。
(
/opt/local/bin/python2.5
) - Python.org から、MacPython
(
python-2.5.2-macosx.dmg
) をダウンロードしてインストール。 (/Library/Frameworks/Python.framework/Versions/2.5/bin/python2.5
) - source からコンパイル。
(
/usr/local/bin/python2.5
)
/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 をするかが決まる。
-
g.plot(x, y):
(x, y) を実線でプロット -
g.plot(x, y, y1):
(x, y) を実線で、(x, y1) を点でプロット -
g.plot(x, y, y1, x1):
(x, y) を実線で、(x1, y1) を点でプロット
-
- default の gnuplot script を "default.gps" というファイルから読み込む。(無ければ何もしない。)
- X11 でも aqua でも動く(筈)。
- Plot1/plot2 のかわりに plot のみを使う。
引数の与え方で、どのような plot をするかが決まる。
.../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 で拡大画像)。
# この関数 v(t) の Fourier 変換 V(f) を求める。 >>> V = fft(v) # この V(f) を plot する。(V(f) は複素数だから、絶対値に直して表示) >>> g.plot(f, abs(V))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 してみた訳だが、驚く程簡単だった。 私はちょっと「感動もの」だと思う。
しかし私には、 この「簡便」という事よりスクリプトがとても「直観的」 になる事の方が嬉しい。例えば、
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 しながら… とか、数式の導出を、シミュレーションで確かめながら(邪道か?) などという場合に、とても見通しが良くなる事は請合い。
232/1,788,162 Taka Fukuda Last modified: Sun Jun 29 17:33:18 PDT 2008