2012年12月15日土曜日

PRML4.2.1 pythonで実装してみた。

PRML4.2章を実装してみた。

とりあえず可視化は成功。
共分散行列が同じでない場合とか
事前確率が違う場合とかも試せてわかってイメージが湧いた。



meshgrid()を使って2次元パラメータの可視化を行ったけど、
作ったメッシュで2次元ガウス分布をもっと効率的にできんかね?(65,66行のメソッド)
少し時間が掛かってしまう。
まぁよしとしよう。

matplotlibで等高線に凡例をつける場合はググると次のようにすることがわかった。
    lines=[]
    lines.append(plt.contour(X1, X2, px_C1, colors="r"))
    lines.append(plt.contour(X1, X2, px_C2, colors="b"))
    actual_lines = [cs.collections[0] for cs in lines] 
    plt.legend(actual_lines, ("px_C1", "px_C2")) 


以下ソースを載っけます。

import numpy as np
from matplotlib import pyplot as plt



class Gauss2D:
    def __init__(self, m, sig):
        self.m = m
        self.d = 2
        self.sig = sig
        self.sig_i = np.linalg.inv(sig)
        
        det = np.linalg.det(sig)**0.5
        self.c = 1/(2*np.pi*det)
        
        
    
    def meshvalue(self, X1, X2):
        """
        get values by meshgrid X1, X2
        return the array of which size is the same with X1 and X2
        SLOW!!!
        """
        if X1.shape != X2.shape:
            raise TypeError("input array shape are not the same!")
        
        Z = np.empty(X1.shape)
        
        for i in range(X1.shape[0]):
            for j in range(X1.shape[1]):
                tmp = np.array([X1[i,j], X2[i,j]]) - self.m
                Z[i,j] = self.c * np.exp(-0.5 * np.dot(np.dot(tmp, self.sig_i), tmp))
        
        return Z
            

    

if __name__ == "__main__":
    fig = plt.figure(figsize=(6,16))
    
    
        
    x1 = np.arange(-1, 1.0, 0.01)
    x2 = np.arange(-1, 1.0, 0.01)    
    X1, X2 = np.meshgrid(x1,x2)
       
    pC1 = 0.5
    pC2 = 1 - pC1    
    
    """define px_C1 and px_C2 as gaussian"""
    m1 = np.array([-0.5, -0.5]) #means
    m2 = np.array([0.5, 0.5])
    sig1 = np.array([[0.1,0], [0,0.1]]) #covarance
    sig2 = np.array([[0.1,0], [0,0.1]])
    g1 = Gauss2D(m1, sig1)
    g2 = Gauss2D(m2, sig2)
    px_C1 = g1.meshvalue(X1,X2)
    px_C2 = g2.meshvalue(X1,X2)
    
    """plot px_C1 and px_C2"""
    fig.add_subplot(211)
    lines=[]
    lines.append(plt.contour(X1, X2, px_C1, colors="r"))
    lines.append(plt.contour(X1, X2, px_C2, colors="b"))
    actual_lines = [cs.collections[0] for cs in lines] 
    plt.legend(actual_lines, ("px_C1", "px_C2")) 

    """calc and plot pC1_x"""
    a = np.log(px_C1*pC1/(px_C2*pC2))
    pC1_x = 1/(1+np.exp(-a))            #sigmoid   
    
    fig.add_subplot(212)        
    plt.imshow(pC1_x[::-1], extent=[-1,1,-1,1], interpolation='nearest')
    plt.colorbar(shrink=0.8,aspect=10)
    plt.title("pC1_x")
    
    
    plt.show()



2012年10月13日土曜日

マチュピチュ 個人旅行の費用

マチュピチュに個人旅行でいくとツアーとどのように違うか少しメモ。

  1. おおまかな日程
    • 7泊10日
    • リマ→プーノ→マチュピチュ→リマ

  2. 費用まとめ(1人あたり)
    • 宿代   10万 
    • 移動費  24万
    • その他   5万
    • 合計   39万

  3. 費用詳細
    • 宿代はハネムーンなので豪華
      • マチュピチュ2泊7万円
      • 残り3万でもその他もそれなりに豪華にできた。
    • 移動費
      • ペルーへの飛行機   19万
      • 国内飛行機2回      2万 (LAN PERUは高いので使ってない 参考
      • マチュピチュへの列車 2.5万(往復)
      • バスツアー        0.5万
    • その他
      • マチュピチュ(1日)+ワイナピチュ(1日)の入場料 1万
      • 食費や土産やタクシー代(使いすぎな気も…)


今回のマチュピチュ個人旅行のポイントは
時間を気にせずマチュピチュの遺跡に滞在できたこと、
ワイナピチュに登れたこと。

昼間は観光客が多いが動きにくいけど、夕方になると人が減ってきて更に夕暮れに遺跡が映えてオススメ。
ワイナピチュも自分たちのペースでのんびり上がって降りてこれる。
団体行動ではなかなかこうした行動は取りづらい。

Sanctuary Lodgeに泊まれば更にのんびりできる。
3食付きでペルーのなかではどれも一番美味しかった。
昼食はビュッフェかアラカルト形式か選べた。ビュッフェにすると他の観光客と同じところで食べる。
美味しかったが日本人が多すぎてせっかく海外に来たのにゲンナリ。


物価も日本よりも安く、今回は宿代など贅沢しているので、
本気だせばもっと費用を抑えていけるはずです。


2012年10月11日木曜日

ペルーの国内の航空会社

マチュピチュに行くにはペルーのクスコに行かなければならない。
クスコに行くにはペルーの首都リマからバスか飛行機がある。


飛行機を選択した場合ペルー国内の航空会社を利用するわけだが、
ペルーのキャリアには3つくらい選択肢がある。
地球の歩き方にものっているように

  1. LAN PERU
  2. STAR PERU http://www.starperu.com/
  3. TACA          http://www.taca.com/
LAN PERUは有名な航空会社だが国内移動の料金には
現地の人向け料金と外国人向け料金が設定されておりかなりの差がある。
日本人とアメリカ人でも差がある。これは意味が分からない。

STAR PERUとTACAはともにウェッブで予約ができ、クレジットカード決済ができるので便利だ。
料金も均一。


今回の旅では
リマ→プーノをTACA
クスコ→リマをSTAR PERU
を利用した。

はじめは何となくSTAR PERUの方が進んでいるイメージで両方共STAR PERUで予約しとったけど、
リマ→プーノ便が理由もなしにキャンセルになったのでTACAを使ってみた。


利用した結果ですが、TACAがおすすめ。
機体も新しく綺麗だったし、空港でのカウンターの数や小ぎれいさがSTAR PERUよりも上だった。
しかもスターアライアンスなのでANAのマイルも貯まります、たぶん。

リマの空港ではカウンターの数が他よりもかなり多かったので勢力をかなり拡大しているのでしょう。

どちらのキャリアも1回ずつしかのっていないのでたまたまSTAR PERUが悪かった可能性もありますが、
今回の旅に限ってはTACAが圧勝です。


以上、参考になれば幸いです。

ペルー、マチュピチュでの高山病と薬について

ペルーでの高山病体験を記録しておきます。

地球の歩き方ペルー編を読むと高山病について書かれていたりしますが、
ダージリン(2100m)、ブータン(2300m)、ネパール(2200m)を旅したときには特になんともなかったので、今回の旅行も特に気にしていませんでしたがひどい目に会いました。



ペルーの標高をまとめると

プーノ(チチカカ湖)   3800m
クスコ                 3400m
マチュピチュ      2400m
リマ             150m

マチュピチュが2400mですが、必ずクスコを経由しないと行けないので3000m級の高さは避けて通れません。



初日の夜にリマについて、2日目すぐにプーノに飛行機で向かいました。
プーノはチチカカ湖のほとりにある町です。
ついた当初、少し動いただけで妙に息切れをしましたが普通にしていれば問題ありませんでした。
初めての体験だったので不思議ですこし楽しかったくらいです。


ホテルにチェックインして少し周りを散策しましたが、
先に嫁の具合が悪くなりました。
「運動不足やけやー」
なんて言っていると夕方には僕も具合が悪くなり、
頭痛と吐き気でその晩は二人共なにも口にできなくなりました。


寝る前に嫁の持参した「ロキソニン」(頭痛薬)を飲んで少し具合がよくなり、
翌日町へ高山病の薬をゲットしに行きました。
日本では医師の処方が必要ですが、
現地では処方箋なしで高山病の薬を買えるとのこと。


事前情報として
外務省のHPによると高山病の薬としてアセタゾラミドAcetazolamideを挙げている。
しかもこう書いてある。
ペルーの薬局で高山病の薬として始めに勧められるのは一般的な頭痛薬だ、と。
しかも、胃腸の弱い方には勧められないとも。


だから予習通り現地の薬局で、
最初に勧められた薬をことわりアセタゾラミドをくれと言いました。
その夜も頭痛と吐き気に襲われたのでアセタゾラミドを飲みました。

しかし具合がいっこうに良くなりません。
ロキソニンを飲んだ嫁は具合がだいぶ良くなりご飯を食べれるようになりましたが、
アセタゾラミドを飲んだ僕はむしろその薬物を吐き出すかのように口にしたものは水ですら吐くようになりました。
結局、頭痛と吐き気で2日間くらい食事もろくに取れずにいましたが、アセタゾラミドを服用したせいでさらに症状が悪化したように思います。


急性高山病も1日から2日で回復するようなので、変な薬を飲んで吐くよりは鎮痛剤で症状を軽めながらしっかりと食事をとって休養した方が良いように思いました。
バスで同じだった日本人の方も現地の高山病の薬は逆効果がある噂があるといっていたので個人差が大きいのかもしれませぬ。


高地を先に経験したためか、4日目以降のマチュピチュはワイナピチュ登山を行なっても高山病の症状はまったく出ませんでした。
マチュピチュはそんなに高くないのでクスコやプーノなどをどう過ごすかがペルー攻略の鍵となるでしょう。

ツアーにするとこの辺も考慮してくれるのでしょうが…それはそれで面白くないわけで。

以上参考になれば幸いです。







マチュピチュ 個人旅行での予約方法

先日個人旅行でマチュピチュにいきました。

マチュピチュには入場制限が掛かっており事前にチケットを入手しないと入場できません。

チケットは
http://www.machupicchu.gob.pe/
から予約してクレジットカードで購入できるのですが…
現地のVISAカードの関係でクレジットカードが機能しないようです。
支払いはカード以外だと現地(ペルー)での支払いになるので時間に余裕がない人には少し面倒。
http://www.honjonet.net/peru/trouble.htmlに詳しいことが書いてます。)

これを解決する手段の一つとして現地代理店に頼む方法があります。
この方法だときっと色々なことがスムーズにいくでしょう。
たとえばこんなサイトがあります。
http://machupicchuyoyaku.com/
http://www.surtrek.jp/peru/howtogetmachupichu.html


これらの代理店はツアーやホテルと一緒みたいですね。
僕は全部のホテルと列車を予約してからこの事実に気づいたので困りました。

個人でなんでも計画を立てる人には結構な痛手です。
僕は泊まるホテルに代行してもらいました。

Sanctuary LodgeとSumaq Hotelに連絡しました。(いちおハネムーンなのでホテルは豪華です。)
文面はこんな感じです。

//////////////////////////////////////
To whom it may concern,

I am ○○ from Japan.
I have made reservation at your Hotel and will stay on October 11th.
We are planning to visit Machu Picchu and tried to buy tickets for entrance through their website by a credit card.
But I found out it was impossible for foreigners to use credit card on that website.
Now there is no way I can purchase the ticket from Japan.

Is it possible for you to perchase the ticket instead of us?
If possible, how much would that be for 2 persons.
Our plan is:
October 11th: Only MachuPicchu
October 12th: MachuPicchu + Huaynapicchu 2G 10:00-11:00 am


Thank you for you time and thoughts.
Sincerley,

○○
addressとか
////////////////////////////////////////


連絡した結果ですが、
Sanctuary Lodge:代金+手数料10%
Sumaq:代金+なぜか70%くらい

なのでSanctuaryLodgeに頼みました。
クレジットカード情報をすべてホテル側に教える必要があるため、
信頼のあるホテルでないと情報漏れが怖いです。
(信頼できるホテルでもやはり怖いことに変わりはないか…)

途中メールが途絶えて詐欺かと思いましたが、
SanctuaryLodgeの経営元のOrient expressに連絡して何とか手配が完了しました。


余談ですがSumaqHotelにとまるくらいならもう少しだしてSanctuaryLodgeに泊まるほうが断然いいです。代行に法外な料金を提示してきたことが印象に残っているのかもしれませんが、ご飯もサービスもロケーションもSanctuaryLodgeの方が良かったです。


以上、参考になれば幸いです。








2012年7月26日木曜日

PyQtでグラフ 完了

PyQwtを使ってグラフを描く。今回はマウスでデータを動かすプログラムを作成。


マウスの座標を取得するにはQwtPlotのinvTransformを使えば良いことが分かった。
ただ、この関数にはキャンパス(QwtPlot.canvas())の座標を与えなければならないので注意。
僕はずっとQwtPlotのウィジットの座標を与えていたようで、少し値がずれていました。

イベントの取得方法はPyQwtのHPの例を参考にしました。
イベントフィルタについてはここを読むとわかる。
今回のようにクラス外部にフィルタを持つことで、柔軟にcanvas()でのイベントを取得できます。
(ただ原理をきちんと理解していないので冗長さはありますが…どうなんでしょう?)

クリックした座標に一番近いデータはQwt.PlotCurve.closestPointで取得できます。
あとはドラッグしている間にそのデータを書き換えるだけです。




ソースも載せときます。
とりあえずグラフでやりたいことはここまでなので、あとはQtでUIを作成していきます。

import sys

from PyQt4.QtGui import QApplication, QWidget, QHBoxLayout 
from PyQt4.Qt import Qt, QPen, QSize, QBrush, QObject, SIGNAL, QEvent
from PyQt4.Qwt5.Qwt import QwtPlot, QwtPlotGrid, QwtPlotCurve, QwtSymbol

import numpy as np
from numpy import pi

class Spy(QObject):
    
    def __init__(self, parent):
        QObject.__init__(self, parent)
        parent.setMouseTracking(True)
        parent.installEventFilter(self)

    # __init__()

    def eventFilter(self, _, event):
        if event.type() == QEvent.MouseMove:
            self.emit(SIGNAL("MouseMove"), event.pos())
        if event.type() == QEvent.MouseButtonPress:
            self.emit(SIGNAL("MouseButtonPress"), event.pos())
        if event.type() == QEvent.MouseButtonRelease:
            self.emit(SIGNAL("MouseButtonRelease"), event.pos())
        return False

    # eventFilter()

# class Spy

class PlotWidget(QwtPlot):
    def __init__(self, title, *args):
        QwtPlot.__init__(self, *args)
        self.setTitle(title)
        self.setCanvasBackground(Qt.white)
        self.setMouseTracking(True)
        
        #grid
        grid = QwtPlotGrid()
        grid.attach(self)
        grid.setPen(QPen(Qt.black, 0, Qt.DotLine)) #make grid dotted-line
        
        self.curve = None
        self.picked_id = None   #picked index by mouse
        self.pick_tol = 5.0     #picking tollerence        
        
        #connect signal and slot
        self.connect(Spy(self.canvas()), SIGNAL("MouseMove"),
                     self.on_move)
        self.connect(Spy(self.canvas()), SIGNAL("MouseButtonPress"),
                     self.on_click)
        self.connect(Spy(self.canvas()), SIGNAL("MouseButtonRelease"),
                     self.on_release)
    
    def on_move(self, pos):
        if self.picked_id is not None:
            #drag the picked data by mouse
            x = self.invTransform(QwtPlot.xBottom, pos.x())
            y = self.invTransform(QwtPlot.yLeft, pos.y())
            
            self.x[self.picked_id]=x
            self.y[self.picked_id]=y
            self.curve.setData(self.x, self.y)
            self.replot()
            
    def on_click(self, pos):
        if self.curve is not None:
            picked = self.curve.closestPoint(pos)
            
            if picked[1] > self.pick_tol:
                self.picked_id = None
            else:
                self.picked_id = picked[0]
                
    def on_release(self, pos):
        self.picked_id = None
                
    def setCurveData(self, title, x, y):
        self.curve = QwtPlotCurve(title)
        self.curve.setPen(QPen(Qt.black, 0))
        self.curve.setSymbol(QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.red), QPen(Qt.red), QSize(10,10)))    
        self.curve.setData(x,y)
        self.x = x
        self.y = y
        self.curve.attach(self)
                
class MultiPlotWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle("multiple graphs")
  
        hlayout = QHBoxLayout()
        self.setLayout(hlayout)
        
        #data creation
        x = np.linspace(-2*pi, 2*pi, 100)
        y1 = np.cos(x)

        #create plots
        self.plot1 = PlotWidget("plot1")
        self.plot1.setCurveData("y=cos(x)", x, y1)

        #add plots to the main widget
        self.layout().addWidget(self.plot1)
               
def main():
    app = QApplication(sys.argv)

    plot = MultiPlotWidget()
    plot.setMinimumSize(500,300)
    plot.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


2012年7月25日水曜日

ヘビでもわかるライトフィールドカメラの原理 その1.1 ライトフィールド(light field)とは

ライトフィールドカメラの「ライトフィールド」とは「光のすべて」という意味である。
すこし大げさな言い方をすると
「ライトフィールドカメラ」=「光のすべて記録するカメラ」となる。


「光のすべて」とはなんなのか。
光の状態をどのように記述するかを考えてみると、
『ある時間』、『ある場所』で、『ある波長』の光が『ある強度』で『ある方向』へ伝搬している…
この状態を表す関数を考えると

時間=1次元
場所=3次元
方向=2次元
波長=1次元

となり、思いついた性質を並べただけで7次元の関数となる。
これら光のすべて記録しておけば、その状況を行ったり来たりすることができるのは想像できるだろうか?
実はそのいい例が映画「The Matrix」のあのシーン。
撮影風景をテレビでみたことある人もいると思うが、カメラを何台も並べてあらゆる方向から来る光を記録して、後から合成している。
http://goo.gl/HeJQk
つまりあれも一種のライトフィールドカメラということである。


これまでのカメラは、

時間→シャッターで一瞬をサンプリング
波長→カラーフィルターで分離

という具合で光のパラメータをCMOSの電荷情報に変換している。
残すは場所(3次元)と方向(2次元)の5次元であるが、実は光には輝度不変則というものがあるので、4次元まで減らすことができる。これは障害物にあたらなければ、光はエネルギーを失うことなく進む、みたいなもので、要するに情報を保存しているので、1つ次元減らしてもOK。ということである。


この4次元で表せられる光のことを論文とかでは”4D Light Field"なんていう。
4D Light Fieldをいかにして捕らえるかが今回説明したいライトフィールドカメラの原理の真髄なのだが、こんなに長文を書くのも久しぶりで疲れたのでまた今度。

あまり厳密な説明はするつもりがないので、
とりあえず今回はライトフィールドがどんなものかざっくりわかってくれたら嬉しいです。
次回は図も含めてライトフィールドとはなんぞやについて説きたい。




pyqwt入門その3 複数グラフの表示

pythonでグラフを描画その3は複数のグラフを描画させる。
これはQwtではなくQtの側の操作。

QwtPlotのオブジェクトを作ってそれをQWidgetにaddWidgetで加える。
それだけです。

データ同士を結ぶ線、左のグラフでは見えなくて、右では黒の線になっている。
実は左では線の色に白を指定して見難くしているだけ。
どうやって線自体を消すのだろう。。。


ソースも今後の参考に載せます。
import sys

from PyQt4.QtGui import QApplication, QWidget, QHBoxLayout 
from PyQt4.Qt import Qt, QPen, QSize, QBrush
from PyQt4.Qwt5.Qwt import QwtPlot, QwtPlotGrid, QwtPlotCurve, QwtSymbol

import numpy as np
from numpy import pi


class PlotWidget(QwtPlot):
    def __init__(self, title, *args):
        QwtPlot.__init__(self, *args)
        self.setTitle(title)
        self.setCanvasBackground(Qt.white)
        
        #grid
        grid = QwtPlotGrid()
        grid.attach(self)
        grid.setPen(QPen(Qt.black, 0, Qt.DotLine)) #make grid dotted-line
        
        self.replot()
        
class MultiPlotWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle("multiple graphs")
        
        hlayout = QHBoxLayout()
        self.setLayout(hlayout)
        
        #data creation
        x = np.linspace(-2*pi, 2*pi, 100)
        y1 = np.sin(x)
        y2 = np.cos(x)        
        
        #create plots
        plot1 = PlotWidget("plot1")
        curve1 = QwtPlotCurve('y=sin(x)')
        curve1.setPen(QPen(Qt.white, 0))
        curve1.setSymbol(QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.red), QPen(Qt.red), QSize(5,5)))       
        curve1.setData(x,y1)
        curve1.attach(plot1)
                
        plot2 = PlotWidget("plot2")
        curve2 = QwtPlotCurve('y=cos(x)')
        curve2.setPen(QPen(Qt.black, 0))
        curve2.setSymbol(QwtSymbol(QwtSymbol.Rect, QBrush(Qt.blue), QPen(Qt.blue), QSize(5,5)))       
        curve2.setData(x,y2)
        curve2.attach(plot2)
        
        #add plots to the main widget
        self.layout().addWidget(plot1)
        self.layout().addWidget(plot2)
        
        
        
def main():
    app = QApplication(sys.argv)

    plot = MultiPlotWidget()
    plot.setMinimumSize(300,200)
    plot.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

2012年7月24日火曜日

pythonでグラフ pyqwt入門その2

matplotlibはなんといってもグラフのクオリティが高いところがいいのだが、少々重たくGUIには向かん。そんなこんなでPyQwtに手を出しけど、Qwtをどれくらい使いこなせるかが鍵。
PyQwtの例はネットにあまりなく、Qwtをあたらないけん。
C++を使える人はいいかも知れんけど、知らん人はqwtのドキュメント読んでもなかなか分からんのよね~

少し苦労して、プロットの形と線を変える方法を発見したのでアップ。
curve.setPen(Qt.QPen(Qt.Qt.blue, 2, Qt.Qt.DotLine))
        curve.setSymbol(Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, Qt.QBrush(Qt.Qt.red),
                                      Qt.QPen(Qt.Qt.red), Qt.QSize(5,5)))

結果は写真のようになる。 EllipseんとこをDiamondとかにしてもよい。形はここをみて好きなのを選ぶ


忘れんように全ソースもメモ
import sys
from PyQt4 import QtGui, Qt
import PyQt4.Qwt5 as Qwt
import numpy as np
from numpy import pi

class SimplePlot(Qwt.QwtPlot):
    def __init__(self, *args):
        Qwt.QwtPlot.__init__(self, *args)
        self.setTitle('simple plot demo')
        self.setCanvasBackground(Qt.Qt.white)
        
        #grid
        grid = Qwt.QwtPlotGrid()
        grid.attach(self)
        grid.setPen(Qt.QPen(Qt.Qt.black, 0, Qt.Qt.DotLine)) #make grid dotted-line
        
        x = np.linspace(-2*pi, 2*pi, 100)
        y = np.sin(x)
        
        curve = Qwt.QwtPlotCurve('y=sin(x)')
        curve.attach(self)
        curve.setPen(Qt.QPen(Qt.Qt.blue, 2, Qt.Qt.DotLine))
        curve.setSymbol(Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, Qt.QBrush(Qt.Qt.red),
                                      Qt.QPen(Qt.Qt.red), Qt.QSize(5,5)))       
        curve.setData(x,y)
        
        self.replot()
        
def main():
    app = QtGui.QApplication(sys.argv)

    plot = SimplePlot()
    plot.setMinimumSize(300,200)
    plot.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()




pythonでグラフ pyqwt入門

python(x,y)に入っていたguiqwtはすごく高級なだけに、なかなかやりたいことがすぐ出来なかった。
ドキュメントがフランス語?みたいなのもあったし。試行錯誤したけど、もう諦めたwプログラムのわかっていない僕が複雑なことをやろうとすると、その場しのぎになって、かえってソースがぐちゃぐちゃしてしまう。

よってもう一つ低級なpyqwtでQtにプロットさせることを考える。
ドキュメントは「C++のqwtをみてね」、といった感じなので初心者には少し取っつきにくけど例を参考に少しずつやっていこう。 http://pyqwt.sourceforge.net/

まずは、シンプルなsin関数の表示をやってみた。




import sys
from PyQt4 import QtGui, Qt
import PyQt4.Qwt5 as Qwt
import numpy as np
from numpy import pi

class SimplePlot(Qwt.QwtPlot):
    def __init__(self, *args):
        Qwt.QwtPlot.__init__(self, *args)
        self.setTitle('simple plot demo')
        self.setCanvasBackground(Qt.Qt.white)
        
        #grid
        grid = Qwt.QwtPlotGrid()
        grid.attach(self)
        grid.setPen(Qt.QPen(Qt.Qt.black, 0, Qt.Qt.DotLine)) #make grid dotted-line
        
        x = np.linspace(-2*pi, 2*pi, 100)
        y = np.sin(x)
        
        curve = Qwt.QwtPlotCurve('y=sin(x)')
        curve.attach(self)
        curve.setData(x,y)
        
        self.replot()
        
def main():
    app = QtGui.QApplication(sys.argv)

    plot = SimplePlot()
    plot.setMinimumSize(300,200)
    plot.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


2012年7月16日月曜日

ヘビでもわかるライトフィールドカメラの原理 まとめ

Lytroのライトフィールドカメラが世間を騒がせてから結構な時間が経ちました。
初めて見たときはまったく原理の想像がつきませんでした。幸いにもLytroのCEO, Ren NgのD論がHPで公開されているので、基本原理はだれでも勉強することができます。
https://www.lytro.com/downloads/resources/renng-thesis.pdf

また、元Adobe社員、現在はQualcommに勤めているTedor Georgievさんのページも大変参考になりました。いろんな資料がおいてあります。
http://www.tgeorgiev.net/

これから少しずつ自分の理解した範囲でLight Fieldカメラの原理(リフォーカスの原理)を明らかにしていきたいと思います。
以下目次です。

1 ライトフィールドとは。
    1.1 ライトフィールド(light field)とは

2. ライトフィールド記録の原理

3. ライトフィールドの処理方法
    3.2 データと分解能


このカメラの原理を勉強して勉強になったのは光線のイメージをより具体的に持てたということです。小学校で結像を理解するときには、光線は2本しか出て来ませんでした(レンズの中心を通るものと、光軸に平行なもの)。それ以上の本数でレンズを理解しようとした人はかなり少数なのではないでしょうか。このカメラの原理自体は100年くらい前に発案されているので、基本原理に立ち返ることがいかに大事かということを思い知らされます。


さて、ライトフィールドカメラはこれまでのカメラを置き換えていくのでしょうか。
正直そんなことはわかりません。時代の予測はいつだって難しいものです。
しかし、今後も確実なことは人間の目はライトフィールドを捉えていないという事実です。
人間は写真という2次元情報からそれ以上のさまざま情報を発起します。
ムービーがあっても写真がなくならないように、
映画ができても、小説がなくならないように、
今後も2次元の写真はなくならないでしょう。人間がそのようにできているからです。

もちろんLight Fieldを捉えてもよいのですが、
大事なのは最終的な2次元的成果物です。
その瞬間をいかに切り抜くかが写真の本質であり続けることに変わりはないでしょう。

Lytroについて追記した。(2014/11/06)
Lytroが日本に上陸してアクセスが増えたのでLytroのすごいと思うところをのべる。


2012年7月15日日曜日

guiqwtのpyplotを使ったグラフ

guiqwtでpyplotを使ったグラフの作成。
matplotlibと同様にかけてストレスがない。
とりあえずメモ。
参考URLを見てもわかるように、機能としては最低限なので、今後はこれ以外のモジュールを模索していきたい。

参考:http://packages.python.org/guiqwt/reference.html#guiqwt-pyplot

import numpy as np
from guiqwt import pyplot as plt

x = np.linspace(-5, 5, 100)
plt.figure(1)
plt.subplot(2,1,1)
plt.plot(x, np.sin(x), "r+")
plt.ylabel("sin")
plt.subplot(2, 1, 2)
y = np.random.rand(len(x))
plt.plot(x, y)
plt.ylabel("random")
plt.show()






guiqwtとmatplotlib

これまでmatplotlibのグラフ機能を勉強してそれをGUIアプリケーションに応用しようと考えていました。matplotlibはとても有名で、資料も豊富なのですが、どうも僕の用途には向かないようです。なぜならグラフをsubplotとして複数(10枚~)表示さえると著しく速度が低下してしまう。データ処理して表示さえるだけならいいのですが、インタラクティブに操作するには大変問題となってしまいます。

OpenGLで開発するしかないか。。。と諦めかけていた矢先、qtの開発環境としてPython(x,y)をインストールしたら、guiqwtなるものを発見しました。しかもサンプル付きで、そのサンプルがとても魅力的。

これはと思ってサンプルをいじって、何枚かグラフを表示させると明らかにmatplotlibよりも速い。

guiqwtとはPyQwt(PyQt4のプロットウィジット)とnumpyやscipyを元にしたもので、効率のよい2Dプロットを実現してくれるもの、らしい。http://packages.python.org/guiqwt/overview.html

たとえば、最低限の機能なら同じように記述できる。
import guiqwt.pyplot as plt # only this line has changed!
import numpy as np
x = np.linspace(-10, 10)
plt.plot(x, x**2, 'r+')
plt.show()


でも、前に書いたみたいにfig.add_subplot(111)などはできなかった。
今後はPyQtの勉強も兼ねてこのguiqwtの勉強をしていこう。



2012年7月1日日曜日

matplotlib その4 マウスで座標の取得

matplotlibでマウスのボタンが押されたときの情報を取得するプログラム。

ここでの取得項目は左から、
押されたボタンの種類(1:右、2:ホイール、3:左)、
マウスの押された場所でのピクセル座標(x, y)
マウスの押された場所でのデータ座標(x, y)


参考URL:http://matplotlib.sourceforge.net/users/event_handling.html



from numpy.random import rand
from pylab import figure, show

def onclick(event):
    print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
        event.button, event.x, event.y, event.xdata, event.ydata)

if __name__ == "__main__":
    fig = figure()
    ax = fig.add_subplot(111)
    ax.set_title("button pressed event demo")
    ax.plot(rand(5))

    fig.canvas.mpl_connect('button_press_event', onclick)
    show()



2012年6月30日土曜日

matplotlib その3(プロットした点をクリック、ハイライトする)


matplotlibでマウスのイベントを取得して、クリックした点のデータをとってくる。
参考URLを勉強がてら少しシンプルにしてみる。
描画データをPointBrowserに関連付けておいて、データをクリックするたびに、その上に黄色い薄い丸を描画するようにしている。


メモ:
plotのpicker=5でクリックしたときの許容範囲を決定。
複数のデータがクリック範囲に入ったときも、そのうち1番最初の1つのみを使う。(ind[0])
mpl_connectを使えば、マウス以外にもイベントを取得できる。ハンドラーというのだろう。(http://matplotlib.sourceforge.net/api/backend_bases_api.html#matplotlib.backend_bases.FigureCanvasBase.mpl_connect)


参考URL:http://matplotlib.sourceforge.net/examples/event_handling/data_browser.html

from numpy.random import rand
from pylab import figure, show


class PointBrowser:
    """
    pass a subplot to __init__
    overwrite the yellow circle on the clicked data
    """
    def __init__(self, fig, ax):
        self.fig = fig
        self.text = ax.text(0.05, 0.95, 'selected: none',
                            transform=ax.transAxes, va='top')


        self.selected,  = ax.plot([], [], 'o', ms=12, alpha=0.4,
                                  color='yellow', visible=False)

    def onpick(self, event):
        """
        it picks up the index of clicked data

        """
        if not len(event.ind):
            return True

        ind = event.ind[0]
        x = event.artist.get_xdata()[ind]
        y = event.artist.get_ydata()[ind]
        clicked = (x, y)

        self.selected.set_visible(True)
        self.selected.set_data(clicked)
        self.text.set_text(' x: %f\n y: %f'%(clicked))
        self.fig.canvas.draw()

if __name__ == "__main__":
    xs = rand(100)
    ys = rand(100)

    fig = figure()
    ax = fig.add_subplot(111)
    ax.set_title('picking demo')
    ax.plot(xs, ys, 'o', picker=5)  # 5 points tolerance

    browser = PointBrowser(fig, ax)
    fig.canvas.mpl_connect('pick_event', browser.onpick)

    show()




matplotlib 軸の目盛り設定

軸の目盛りは自動で最大値をつけてくれるけど、
手動で付けたい時はset_yticks(list)を使う。

def main():
    fig = figure()
    ax1 = fig.add_subplot(111)
    ax1.plot(rand(10))
    ax1.set_yticks(np.arange(0, 1.1, 0.1))

    show()

if __name__ == "__main__":
    main()







matplotlib その2 (複数のプロット)

matplotlib で複数のグラフを表示する。

1つのウィンドウに2つのグラフを表示する場合
from matplotlib.pyplot import figure, show
import numpy as np
from numpy.random import rand

def main():
    fig = figure()
    ax1 = fig.add_subplot(211)
    ax1.plot(rand(10))
    ax1.set_yticks(np.arange(0, 1.1, 0.1))

    ax2 = fig.add_subplot(212)
    ax2.plot(rand(10), 'o')
    show()

if __name__ == "__main__":
    main()


2つのウィンドウにそれぞれプロットするときは
    fig = figure()

    ax1 = fig.add_subplot(111)
    ax1.plot(rand(10))
    ax1.set_yticks(np.arange(0, 1.1, 0.1))

    fig = figure()
    ax2 = fig.add_subplot(111)
    ax2.plot(rand(10), 'o')
    show()





fig2としなくても描画はできるようだ。
試しにfig=figure()を2回読んだときのfigの中身を調べてみたら
numberとかいうのがあって、それが2になっていた。
以下参考までに
>>> fig = figure()
>>> fig = figure()
>>> fig.__dict__
{'_agg_filter': None,
 '_alpha': None,
 '_animated': False,
 '_axobservers': [],
 '_axstack': ,
 '_cachedRenderer': None,
 '_clipon': True,
 '_clippath': None,
 '_contains': None,
 '_dpi': 80,
 '_gid': None,
 '_hold': True,
 '_label': '',
 '_lod': False,
 '_oid': 0,
 '_picker': None,
 '_propobservers': {},
 '_rasterized': None,
 '_remove_method': None,
 '_snap': None,
 '_transform': None,
 '_transformSet': False,
 '_url': None,
 '_visible': True,
 'artists': [],
 'bbox': TransformedBbox(Bbox(array([[ 0.,  0.],
       [ 8.,  6.]])), Affine2D(array([[ 80.,   0.,   0.],
       [  0.,  80.,   0.],
       [  0.,   0.,   1.]]))),
 'bbox_inches': Bbox(array([[ 0.,  0.],
       [ 8.,  6.]])),
 'callbacks': ,
 'canvas': ,
 'clipbox': None,
 'dpi_scale_trans': Affine2D(array([[ 80.,   0.,   0.],
       [  0.,  80.,   0.],
       [  0.,   0.,   1.]])),
 'eventson': False,
 'figure': None,
 'figurePatch': ,
 'frameon': True,
 'images': [],
 'legends': [],
 'lines': [],
 'number': 2,
 'patch': ,
 'patches': [],
 'show':  at 0x03A35730>,
 'subplotpars': ,
 'suppressComposite': None,
 'texts': [],
 'transFigure': BboxTransformTo(TransformedBbox(Bbox(array([[ 0.,  0.],
       [ 8.,  6.]])), Affine2D(array([[ 80.,   0.,   0.],
       [  0.,  80.,   0.],
       [  0.,   0.,   1.]])))),
 'x_isdata': True,
 'y_isdata': True}


matplotlib その1 (グラフ表示)

これからmatplotlibの使い方をメモしていく。
最終的にはインタラクティブなグラフを作りたい。
例えばデータ点をドラッグしてデータを動かしたり、クリックで編集したり。

まずはグラフの表示。
def main():
    ax = figure().add_subplot(111)
    ax.set_title('test')
    ax.set_ylabel('ylabel')
    ax.plot(rand(10))
    ax.plot(rand(10), 'o')
    show()

if __name__ == "__main__":
    main()

調べたことの覚書:

  1. figure(http://matplotlib.sourceforge.net/api/figure_api.html)
    • すべてのプロット要素を含んだ属性(Artist,Figure)を持つらしい。
  2. add_subplot(111)





2012年6月24日日曜日

Pythonでpwdとかcdとかlsとか


Pythonでpwdとかcdとかlsとか使うには
osモジュールを使うらしい。
具体的には、
>>> import os
>>> os.getcwd()
'C:\\Program Files (x86)'
>>> os.getcwd()
'C:\\Program Files (x86)\\PyScripter'
>>> os.listdir('.')
['Lib',
 'locale',
 'PyProject.ico',
 'PyScripter.chm',
 'PyScripter.exe',
 'unins000.dat',
 'unins000.exe']


2012年6月19日火曜日

Python クラスメソッドのselfにはインスタンスが渡されるらしい。

クラスメソッドの第一引数にはselfが出てくる。
例えば、簡単な例をつくると、
class Person:
    def __init__(self, name):
        self.name = name
    def changeName(self, name):
        self.name = name

if __name__ == "__main__":
    taro = Person("taro")
    jiro = Person("jiro")
    print taro.name, jiro.name

    taro.changeName("tatsuro")
    jiro.changeName("eijiro")
    print taro.name, jiro.name
changeNameを呼び出したとき、引数には名前(文字列)しか与えていないが、
どうやら、自動的にselfにはtaroのインスタンス、またはjiroのインスタンスが渡されているようだ。



Python 簡単なクラスの作成法

Pythonでインタラクティブにクラスを生成する方法。
>>> class person: pass
... 
>>> person.name = "taro"
>>> person.age = 26
>>> print person.name
taro
属性(attribute)を後付けで定義している。
クラスのオブジェクトを定義しただけで、まだインスタンスは作っていない。
インスタンスを生成する。
>>> x = person()
>>> print x.name
taro



クラスにある属性を調べる
なぜかインスタンスのほうは定義したものしか現れない。
呼ばれるまで作らないということなのか??
>>> x.name = "jiro"
>>> person.__dict__.keys()
['age', '__module__', '__doc__', 'name']
>>> x.__dict__.keys()
['name']


どのクラスに関連付けされているかを調べるには
>>> x.__class__


あと付けで関数を定義して、それをクラスメソッドにする。
>>> def firstLetter(self):
...     return self.name[0]
... 
>>> firstLetter(x)
'j'
>>> person.method = firstLetter
>>> x.method()
'j'






2012年6月14日木曜日

モジュールについて

外部ファイルに記述された関数や変数(モジュール)に対して

モジュールを使う利点は3つ挙げられる。

  1. コードの再利用
  2. 名前の衝突を防ぐ
  3. データや関数の共有


Pythonでモジュールを使うには、importやfromを使うが、


import  モジュール全体を取り込む
from    あるモジュールの特定の名前を取り込む

import文が実行されると、次の3ステップが行われる。

  1. 該当するファイルを見つける。
  2. コンパイルする(.pycができる)。
  3. 上から下まで実行される。
たとえばimport bと書いた時、bに拡張子は付けない。
つまりb.pycが呼ばれるときもある。優先順位は539ページにあるのでチェックすべし。


初めてのPython 20章その4 デフォルト引数使用時の注意

デフォルト引数はdef文が実行されるときに定義される。
関数が呼ばれるときは何もしない。
>>> def saver(x=[]):
...     x.append('aho')
...     print x
...     
>>> saver([4])
[4, 'aho']
>>> saver()
['aho']
>>> saver()
['aho', 'aho']
>>> saver([1])
[1, 'aho']
>>> saver()
['aho', 'aho', 'aho']
>>> 

デフォルト引数はグローバル変数のように生き残るが、
名前が衝突するようなことはない




python. and とか or とか notとか

and, or, notの動作についての確認メモ

>>> 1 or 3    #左がtrueでなければ右のを返す
1
>>> 0 or 3
3
>>> [] or 3
3
>>> [0] or 3
[0]

>>> 1 and 2, 0 and 3 #左がTrueなら右のを返す。
(2, 0)
>>> [] and 4
[]
>>> 





2012年6月13日水曜日

初めてのPython 20章 その3 (timer module)



関数の実行時間を計測するタイマー。
使えそうなのでメモしておく。


>>> import time
>>> reps = 1000
>>> repslist = range(reps)
>>> 
>>> def timer(func, *pargs, **kargs):
...     start = time.clock()
...     for i in repslist:
...         ret = func(*pargs, **kargs)
...     elapsed = time.clock() - start
...     return (elapsed, ret)
... 


初めてのPython20章 その2

とりあえず20章のつづき。

まずはzip関数とシーケンスを分解してタプルで返す
>>> zip([-2, -1, 0])
[(-2,), (-1,), (0,)]
>>>
>>> zip([-2, -1, 0], [3, 2, 1, 0])
[(-2, 3), (-1, 2), (0, 1)]



関数に複数の引数を与え、それをzip関数で解凍する
>>> def mymap(func, *seqs):
...     return [func(*args) for args in zip(*seqs)]
zip関数を自作すると以下のようになる。
while all(seqs)に注目
>>> def myzip(*seqs):
...     seqs = [list(S) for S in seqs]                #各引数をリストに直したものをseqsに入れる
...     res = []
...     while all(seqs):                              #各引数について先頭のものを消去しながらループ
...         res.append(tuple(S.pop(0) for S in seqs))
...     return res
... 
>>> myzip([1,2,3])
[(1,), (2,), (3,)]

ここでallはリスト内の各要素が反復可能か調べるみたい
anyとかいうのもある。
>>> all([1,2,3])
True
>>> all([1,2,0])
False
>>> all([[1,2], [0]])
True
>>> all([[1,2], []])
False
>>> all([])
True

dictionaryの反復はkeyでアクセスする。
>>> d = {'jap': 35, 'ame': 2, 'eng': 0}
>>> for key in d:
...     print key, d[key]
...     
ame 2
jap 35
eng 0
>>> 

リストをfor文で作れるがセットでは違ってくる(重複するのを避ける)
>>> [x + y for x in [1,2,3] for y in [4, 5, 6]]
[5, 6, 7, 6, 7, 8, 7, 8, 9]
>>> {x + y for x in [1,2,3] for y in [4,5,6]}
set([5, 6, 7, 8, 9])


2012年6月8日金曜日

初めてのPython20章

この章リストやforループの応用について書かれてあるようだ。14章の続きみたいなものらしい。

例えば19章のmap関数を使わなくてもリストの表現で次のように掛ける。
>>> [x+10 for x in [0, 1, 2, 3]]
[10, 11, 12, 13]
更にif文を加えるとfilter関数のようになる。
>>> [x for x in range(-5, 5) if x > 0]
[1, 2, 3, 4]
このfor文は何個も続けて(nest)させることができる。
下の2つは別表現で同じことをやっている。
>>> [x * y for x in [0, 1, 2] for y in [3, 4, 5]]
[0, 0, 0, 3, 4, 5, 6, 8, 10]

>>> l = []
>>> for x in [0, 1, 2]:
...     for y in [3, 4, 5]:
...         l.append(x*y)
... 
>>> l
[0, 0, 0, 3, 4, 5, 6, 8, 10]
ちなみに本文によると、これらのリスト表現はmapなどより若干早いとのこと。


続いてはgeneratorと言うものについて。
関数ではreturnで戻り値を返すわけだが、yieldで返すこともできる。
yieldで値を返したときには、関数がその状態を保持してくれているみたいだ。
次の状態に遷移させるにはnext()を使う。具体的には以下のようになる。
>>> def gen(N):
...     for i in range(N):
...         yield i*2
...         
>>> x = gen(3)
>>> x.next()
0
>>> x.next()
2
>>> x.next()
4
>>> x.next()
Traceback (most recent call last):
  File "", line 1, in 
StopIteration
その都度値を生成するので、大きなリストを作るときに役立つのだろう。


yieldは式なので、=の右辺に持ってきたりもできる。
するともう少し高度な使い方が出来るとのこと。
そこで登場するのがsend()メソッド。
generatorとのコミュニケーションを行うことができるのだ。
なんとか理解できたけど、どんな使い方があるのだろうか...
例を示すとこうなる。
>>> def gen():
...     for i in range(5):
...         x = yield i*2
...         print "yes", x
... 
>>> g = gen()
>>> g.next() #yieldまでgeneratorを進める。ここで一度yieldを呼ばずsend()をするとエラーになる。
0
>>> g.next() #next()やsend()をすると止まっていたgeneratorが動くき次のyeildまで進む。
yes None
2
>>> g.send(100) #send()でxに値を与えることができる。
yes 100
4
>>> g.next()
yes None
6
>>> 

上のgeneratorはgenerator関数。 generator式(expression)というのもある。
これらgeneratorは1つのオブジェクトであり、
何個も作って途中で止めておいたり、なんてできない。
>>> g = (c*2 for c in "apple") #generator expression
>>> i = iter(g)                #イタレータを登録
>>> i is g
True
>>> i.next()
'aa'
>>> g.next()
'pp'
>>> i.next()
'pp'
>>> i.next()
'll'
>>> g is i                     #同じオブジェクト
True
>>> 

続く…

2012年6月5日火曜日

初めてのPython 19章

19章はもう少し関数について


関数を再帰的に呼び出す
isinstanceで型を調べるようだ。
>>> def sumtree(L):
...     tot = 0
...     for x in L:
...         if not isinstance(x, list):
...             tot += x
...         else:
...             tot += sumtree(x)
...     return tot
... 
>>> L = [1, [2, [3,4], 5], 6, [7, 8]]
>>> sumtree(L)
36

関数はオブジェクトなので引数に渡すこともできる。
関数と引数をリストにしてfor文で実行してみる。
>>> def sayhello(func, arg): 
...     func(arg)
...     
>>> sayhello(func, 'morning') #funcという関数を渡す
morning
>>> schedule = [(func, 'hello'), (func, 'morning')]
>>> for (f, arg) in schedule:
...     f(arg)
...     
hello
morning
>>> 


続いてlambdaについて勉強する
lambdaはdefとは違い式である→defが書けないところにも書けたりする。
シンプルな記述が可能になるとこのこと。
まずは基本。
>>> f = (lambda x = 3, y = 4: x**2 + y**2)
>>> f()
25

リストにlambdaを定義してこんなこともできるのら。
>>> l = [lambda x: x**2,
...      lambda x: x**4,
...      lambda x: x**8]
>>> 
>>> for f in l:
...     print f(2)
...     
4
16
256
>>> 

>>> d = {"plus": (lambda x, y: x + y),
...      "mult": (lambda x, y: x * y),
...      "pow": (lambda x, y: x**y)}
>>> d["plus"](2,3)
5

シーケンス(リストなど)を扱う関数にmapやfilter, reduceというものがある。
これらの関数は自作でいちいちその関数を定義するよりも速く動く。
まず、マップについて。使い方はこうなる。
>>> nums = [0, 1, 2, 3]
>>> func = lambda x: x + 10
>>> map(func, nums)
[10, 11, 12, 13]
関数が2つの引数を取るなら、リストを2つ渡してもよい。
>>> map(pow, nums, [0, 1, 2, 3])
[1, 1, 4, 27]

続いてfilter。
filterはその名の通り、条件をつけてシーケンスにフィルターを掛けることができる。
>>> func = lambda x: x > 0
>>> filter(func, range(-3, 3))
[1, 2]

reduceはリストを1つにまとめるからそういう名前になったのだろうか。
使い方はこうだ。
>>> func = lambda x,y: x + y
>>> reduce(func, [0, 1, 2, 3])
6

と言う感じで次の章へ~


初めてのPython 18章

18章は引数について

Immutable(integer, string)などは値が渡さえる。
Mutable(list, dictionary)などは参照(pointer)が渡される。
>>> def changer(a, b):
...     a = 2
...     b[0] = "spam"
...     
>>> x = 1
>>> l = [1,2]
>>> changer(x, l)
>>> x
1
>>> l
['spam', 2]


リストなどの内容を変更したくないときはコピーを渡すか、関数ないでコピーを作る
>>> changer(x, l[:])
>>> def changer(a, b):
...     b = b[:]


複数のオブジェクトをタプルとしてreturnできる。
>>> def multiple(x, y):
...     x = 2
...     y = [3, 4]
...     return x, y
... 
つづく…

2012年6月3日日曜日

ミシュラン フランス料理の行けそうなものをピックアップしてみる。

まずはリスト。
http://blog.livedoor.jp/luliecross/archives/52235096.html


モナリザ☆ リーズナブルらしい。。。
http://www.monnalisa.co.jp/top.html

なりさわさん☆☆
http://www.narisawa-yoshihiro.com/jp/menu.html

小田原にある☆ 雰囲気よし。
http://herlequin.com/herlequinbis/menu/03.html
http://rirutomo527.blog79.fc2.com/blog-entry-330.html


横浜栄区☆
http://cheznaka.easy-magic.com/files/cheznaka/dinner01.htm?PHPSESSID=d194ea843c2eb259cfb65b3887035785

ty お店3件とも星(1~2個)を獲得している。
http://www.tateruyoshino.com/index.html

あのピエールの店☆☆
http://www.anaintercontinental-tokyo.jp/pierre_gagnaire/index.html

あのKoujimuraのお店☆☆
http://www.koji-shimomura.jp/index.html

カーエム☆☆ 当日予約はダメ
http://www.km-french.jp/index.html

代官山にある☆
http://www.augoutdujour-group.com/la/info.html


ふぅ~

初めてのPython 17章

lambdaを関数にネストする
>>> def func():
        x = 4
        action = (lambda n: x**n)
        return action
>>> x = func()
>>> x(4)
256
ループ内でlambdaを定義した場合は最後の変数が使われるので注意
>>> def makeActions():
...     acts = []
...     for i in range(5):
...         acts.append(lambda x: i**x)
...     return acts
...
>>> acts = makeActions()
>>> acts[0](2) #4**2になる
16
>>> acts[0](0) #4**0
1
>>> acts[2](2) #4**2
16

こうならないためにはデフォルト引数で指定しておく。
lambdaが作られるときの値がつかわれる。
>>> def makeActions():
...     acts = []
...     for i in range(5):
...         acts.append(lambda x, i=i: i**x)
...     return acts
...
>>> acts = makeActions()
>>> acts[0](2)
0
>>> acts[2](2)
4

nonlocalは飛ばして次へ~

はじめに

このブログは「初めてのPython」で学習した表現を忘れないためにメモしておくことが目的。
初めてのPythonに目に通しながらPythonの表現を勉強していく。
C++とJavaはやったことあるけど、それにはないPythonならではのスタイルを味わいたい。


ちなみにその他読んでいる本(読んでいきたい本)は
パターン認識と機械学習と
Physically Based Rendering, Second Editionと
はじめてのCUDAプログラミング

この辺と光学関連の勉強も適時載せていきたい。