edgyのgs-esp

gs-espの8.15.2にはCJKの扱いにバグがあるらしい。
ubuntu edgyのgs-espはまさにこれが原因で日本語が表示できない。
試しにfeistyのパッケージ(8.15.4)を持ってきてビルドし直しインストールしたら解決した。
http://packages.ubuntulinux.org/feisty/text/gs-esp

ちなみにetchのgs-espは8.15.3なのでセーフ。

fluxboxのfullscreen関連のバグ

gnomeがあまりに重たいので、fluxbox-1.0rc2をソースからコンパイルしてインストールしてみた。結構よさげだったけどOpenofficeのImpress(2.0.2)でスライドショーをしようとすると全画面表示にならない。

というわけでパッチを書いてみた。debian sargeで動作確認済み。

--- Window.cc.orig      2006-11-08 13:22:26.276659700 +0900
+++ Window.cc   2006-11-08 13:10:10.075900913 +0900
@@ -1636,12 +1636,16 @@

         // clear decorations
         setDecorationMask(0);
+        // put resizable flag
+        bool resizable = isResizable();
+        setResizable(true);

         // be xinerama aware
         moveResize(screen().getHeadX(head), screen().getHeadY(head),
                    screen().getHeadWidth(head), screen().getHeadHeight(head));
         moveToLayer(::Layer::ABOVE_DOCK);

+        setResizable(resizable);
         fullscreen = true;

         stateSig().notify();

副作用があるかどうかは知らない。
xfce4でもちょい重いし(贅沢か?)、fluxboxは結構いいかも。

scipy.stats

scipy.statsモジュールには統計には乱数に限らず統計学に関する関数がたくさん。

from scipy import *
# データはあんまり意味なし
x = arange(0.0, 2*pi, 0.01)
y = sin(x)

# 幾何平均
print stats.mean(y)      # -1.72551106802e-06
# stats.varが分散 (sigma^2)
print sqrt(stats.var(y)) # 0.707286084386

どっちともaxisというoptional argumentを取れる。
多次元の場合はaxisの方向にそって平均や分散を求めることができる。
大したこと無い関数だけど多次元の場合にも使えるし、
イチイチ考える必要がないからちょっと便利。

timeit

timer = timeit.Timer(stmt='print scipy.sum(a)',
                     setup='import scipy; a = scipy.arange(100.0);')
print "time = ", min(timer.repeat(3, 100))

これは単純にstmtで与えたpython codeを実行した時の実行時間を測るらしい。
いちいちsetupとかしなきゃいけないし、全てを文字列で与えるのがうざい。

t1 = time.time()
# exec some code
t2 = time.time()
print t2 - t1

でもとりあえず実行時間は測れる。どっちがいいかは用途によるか?

hotshotモジュール

python codeのプロファイラ。
Cの拡張モジュールの時間は換算されない。当り前か?
まぁpython codeのボトルネックは発見できるわけだけど、scipyとかは
外部モジュール使いまくりなのであんまり意味は無い。
weaveコードの時間を測るのにも使えない。

import hotshot

def test(a, b, c):
    # 重たい処理をすべし
    print a, b, c

prof = hotshot.Profile('prof.log')   # ファイルオブジェクト?
result = prof.runcall(test, a, b, c) # コード実行
prof.close()
report = hotshot.stats.load("prof.log")
stats.strip_dirs()                   # この辺は
stats.sort_stats('time', 'calls')    # 好みに応じて
stats.print_stats(20)

C++コードのインライン埋め込み

from scipy import *
converters = weave.converters

def weave_func(x):
  y = zeros(x.shape, dtype=x.dtype)
  code = """
  for(int i=0; i < Nx[0]; i++) {
    y(i) = sin(x(i)) * cos(x(i));
  }
  """
  # use blitz array for C++
  weave.inline(code, ['x', 'y'], type_converters=converters.blitz)
  return y

def py_func(x):
  return sin(x) * cos(x)

x = arange(0.0, 2*pi, 0.02)
y1 = weave_func(x)
y2 = py_func(x)

weave_funcとpy_funcは同じ計算を実行している。
weave_funcではC++のコード(codeという文字列がインラインで実行されるC++のコード)が必要な時には自動的にコンパイルされて実行される。

py_funcでもループはCで実行されるが、かけ算や足し算の度に一時オブジェクトが生成されるので効率が悪くなる。それに対してweave_funcではそれがない。ただしC++のコードの呼び出しオーバーヘッドがかかるので一概に高速化になるかどうかは定かでは無い。

ちなみに配列をblitzの配列オブジェクトではなく普通のポインタとして使うことも可能。この方が早いらしいが、何かとblitzの方が便利。

http://www.scipy.org/PerformanceTips参照のこと。