湯島 タイズ

東大病院の出入り口,竜岡門からすぐにある喫茶店.静かで薄暗い店内だったので写真は自重.バーカウンターの向こうには珈琲器具がならぶ.注文すると,その器具で豆を挽き,お湯をポットからポットに3度,4度と移し替えて温度を調整し,湯滴を慎重に慎重に垂らして珈琲を淹れてくれる.こんなに丁寧に珈琲を淹れてくれる店は今まで見たことが無かった.濃厚に珈琲の風味を感じるけど,胸焼け感も焦げっぽさも無くて美味しい.今まで知らなかったことを後悔した.
東大近辺に喫茶店は多くあるけど,美味しい珈琲が飲みたければ絶対にここに行くべき.ケーキも美味しいとの噂.

根津 芋甚

暖かくなってくると,散歩がしたくなる.東大からすぐの根津は谷中・千駄木と並んで下町風情を残す地域で,ぶらぶらするのに最適.飲食店も焼き鳥「小松」,うどん「根の津」「釜竹」,焼酎「駅馬車」など充実している.もはや文京ではないけど上野桜木まで少し足を伸ばせばケーキの名店「イナムラショウゾウ」もあるし,このエリアの食の充実度は素敵すぎる.
歩き疲れたら,甘いものを.今回は根津駅からすぐの甘味処,芋甚の抹茶モナカをテイクアウト.

音がするくらいサクサクの軽いモナカの中に,上品な甘さのアイス.抹茶の香りもとても良く,適当に抹茶フレーバーを混ぜ込んだそこらへんのアイスとは全くの別物.これで140円は安すぎる.このモナカをお供に食べ歩きをすれば,根津の散歩がもっと楽しめる.すぐ近くには行列のできる「根津のたいやき」もあり,これも食べ歩きにおすすめ.

お手軽線形補間クラスの実装

うちの研究室では組み込み開発の占める割合がすごく大きいので,自分も含めてメンバはSTLだったりboostだったりC++0xだったりに馴染んでいない.それが研究室全体の生産性を妨げている部分があるなーと感じていたので,修論が終わってから研究室内でC++講座的なものを開催している.そこで題材にした簡単な線形補間クラスのことをせっかくだから日記のネタに.

お題

以下のように書ける,線形補間クラスが欲しい.補外は考えない.スレッドセーフも考えないし,桁落ちもとりあえず考えない.ただし,なるべく色んな型に対して使えるジェネリックなクラスにしたい.

int main(void){
    LI<double, double> l;
 
    // (x,y)を登録
    l.append(0, 0.5);
    l.append(1, 1);

    // 登録済みのkeyに対しては対応するvalueを返す
    std::cout << l[0] << std::endl; // "0.5"
    std::cout << l[1] << std::endl; // "1"
    // 登録されていないものは線形補間の結果を返す
    std::cout << l[0.5] << std::endl; // "0.75"
}

STLを知っていると,operator[]の呼び出しのうち,最初の2つはmapの動作そのものであることにすぐ気づく.最後の1つだけがmapと違う動作で,これをどう表現するかという問題*1

書いたもの

やってることはシンプルだけど,mapやSTLアルゴリズムを知らずに全部自力で実装するのは大変.STLC++0xを使うとこんな感じに短く書ける.

#include<assert.h>
#include<map>
#include<algorithm>
#include<functional>

template<typename X = double, typename Y = double>
class LI {
public:
    typedef std::map<X, Y> Points;

    LI(){}

    template<class Iter>
    LI(Iter first, Iter last) : points_(first, last) {}

    void append(X x, Y y){
        points_[x] = y;
    }

    Y operator[] (X x) const{
        assert(!points_.empty());
        //xがinsert済みのものと一致していればその値を返し,そうでなければ補間計算の結果を返す
        return points_.find(x) == points_.end() ? interpolate_(x) : points_.at(x);
    }

private:
    static bool greater_(typename Points::value_type p, X x){
        return p.first > x ? true : false;
    }

    Y interpolate_(X x) const{
        //xを超える最小のpointを指すイテレータ
        auto it_h = std::find_if(points_.begin(), points_.end(), 
                                 std::bind2nd(std::ptr_fun(greater_), x));

        //補外が必要になるようなケースはassertで弾く
        assert(it_h != points_.begin() && it_h != points_.end());

        //xを下回る最大のpointを指すイテレータ
        auto it_l = it_h;
        it_l--;

        return linear_((*it_l).first, (*it_l).second, (*it_h).first, (*it_h).second, x);
    }

    Y linear_(X x1, Y y1, X x2, Y y2, X x) const{
        return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
    }

    Points points_;
};

ここでは補間結果のキャッシュは取らず,逐一計算を実行している.std::bind2nd(std::ptr_fun(greater_), x)とか,greater_の引数が非対称だったりするのがややキモいけど,他は素直な実装.STL無しで同等の安全性を持ったクラスを書くのは相当に大変だろう.
mapのメンバ関数atはC++0xから追加されたもの.operator[]と比べると

  • 渡されたKeyに対応する要素が無い場合,例外を投げる
  • constメンバである

という2点が異なる.ここではstd::findの後ろで呼び出すために例外が投げられない*2こと,「constが使えるときには必ず使え」の鉄則から,atを使用してLI::operator[]をconstにしている.

なるべくジェネリック

ところで,わざわざstaticメンバ関数greater_なんてものを定義しなくても,STLの関数アダプタstd::greaterを使ったほうがクラスがすっきり書ける.

#include<assert.h>
#include<map>
#include<algorithm>
#include<functional>

template<typename X = double, typename Y = double>
class LI {
public:
    typedef std::map<X, Y> Points;

    LI(){}

    template<class Iter>
    LI(Iter first, Iter last) : points_(first, last) {}

    void append(X x, Y y){
        points_[x] = y;
    }

    Y operator[] (X x) const{
        assert(!points_.empty());
        //xがinsert済みのものと一致していればその値を返し,そうでなければ補間計算の結果を返す
        return points_.find(x) == points_.end() ? interpolate_(x) : points_.at(x);
    }

private:
    Y interpolate_(X x) const{
        //xを超える最小のpointを指すイテレータ
        auto it_h = std::find_if(points_.begin(), points_.end(), 
                                 std::bind2nd(std::greater<Points::value_type>(), std::make_pair(x, Y())));

        //補外が必要になるようなケースはassertで弾く
        assert(it_h != points_.begin() && it_h != points_.end());

        //xを下回る最大のpointを指すイテレータ
        auto it_l = it_h;
        it_l--;

        return linear_((*it_l).first, (*it_l).second, (*it_h).first, (*it_h).second, x);
    }

    Y linear_(X x1, Y y1, X x2, Y y2, X x) const{
        return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
    }

    Points points_;
};

これでも冒頭に書いたアプリケーションコードは全く問題なく動く.ところが,このバージョンは型Yに対して新たに次の制約を課す.

  • デフォルトコンストラクタが存在するか,組み込み型であること
  • operator<(const Y&,cosnt Y&)が定義されていること

std::greater >はpairのoperator<を呼び出すが,これはKeyだけでなくValueのoperator<も要求する.たとえばVCでは次のように実装されており,Y型のsecondについての比較が定義されていなければならない.

template<class _Ty1,
    class _Ty2> inline
    bool operator<(const pair<_Ty1, _Ty2>& _Left,
        const pair<_Ty1, _Ty2>& _Right)
    {	// test if _Left < _Right for pairs
    return (_Left.first < _Right.first ||
        !(_Right.first < _Left.first) && _Left.second < _Right.second);
    }

これに対して最初のバージョンでは,直感的に線形補間に必要だと思われるoperatorだけが備わっていれば良い.たとえばstd::complexや,行列ライブラリEigenのMatrixインスタンスに対しても補間が行える.

#include<iostream>
#include<Eigen/Core>
#include "LI.h"

int main(void){
    Eigen::Vector3d v1(1, 2, 3);
    Eigen::Vector3d v2(2, 4, 6);

    LI<double, Eigen::Vector3d> l;
    l.append(0, v1);
    l.append(1, v2);

    //Vector3dに対するoperator<が無いため,2番目のバージョンではコンパイルが通らない
    std::cout << l[0] << std::endl;// "1 2 3"
    std::cout << l[1] << std::endl;// "2 4 6"
    std::cout << l[0.5] << std::endl;// "1.5 3 4.5"
}

ポリシー・クラス

作成した線形補間クラスのpublicインターフェースは,appendで値のペアを登録し,operatorで補間込みの値を得るというだけだった.これは線形に限らず他の補間アルゴリズムでも共通に使える.そこで,線形補間クラスを一般化した補間クラスを設計することを考える.これはさっきのコードの一部を別のクラスに括り出すだけで簡単に実現する.

template<class X, class Y>
class Linear {
public:
    Y interpolate(X x, const std::map<X,Y>& points) const{
        auto it_h = std::find_if(points.begin(), points.end(),   
                                 std::bind2nd(std::ptr_fun(greater_), x));

        assert(it_h != points.begin() && it_h != points.end());

        auto it_l = it_h;
        it_l--;

        return linear_((*it_l).first, (*it_l).second, (*it_h).first, (*it_h).second, x);
    }

private:
    static bool greater_(typename std::map<X,Y>::value_type p, X x){
        return p.first > x ? true : false;
    }

    Y linear_(X x1, Y y1, X x2, Y y2, X x) const{
        return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
    }
};

template<typename X = double, typename Y = double, template<class,class>class InterpolatingPolicy = Linear>
class Interpolation : public InterpolatingPolicy<X,Y>{
public:
    typedef std::map<X, Y> Points;

    Interpolation(){}

    template<class Iter>
    Interpolation(Iter first, Iter last) : points_(first, last) {}

    void append(X x, Y y){
        points_[x] = y;
    }

    Y operator[] (X x) const{
        assert(!points_.empty());
        //xがinsert済みのものと一致していればその値を返し,そうでなければ補間計算の結果を返す
        return points_.find(x) == points_.end() ? interpolate(x, points_) : points_.at(x);
    }

private:
    Points points_;
};

Interpolationクラスは第三引数を省略すればこれまで通り線形補間を実行する.必要であれば自分でinterpolate関数を持った補間ポリシークラスを実装し,引数に与えてやれば良い.このような外部からアルゴリズムを付与するクラスをポリシー・クラスと呼ぶ.

まとめ

STLを知っておくだけで,再利用性の高い線形補間クラスを50行に満たない簡単な実装で得ることができた.ふつうSTLの内部実装を意識する必要は無いが,今回のようにSTLアルゴリズムが暗黙に要求するインターフェースを理解しておくと,ジェネリックな設計に役立つこともある.

*1:mapの場合はValue型のデフォルト値を返す

*2:マルチスレッドを考えだすとややこしい

一人暮らしの男性はまずスパチュラを買うのがいいかも

ひとり暮らしの男性は○○を買えシリーズ。

ひとり暮らしの男性に、電気フライヤーのススメ
ひとり暮らしの男子にはシリコンスチーマーがぜったいにおすすめ - Future Insight

スチームケース、良いですよね。ウチでもジャガイモを皮ごと蒸してピュレにしたり、魚と玉ねぎをぶち込んでメインディッシュにしたりと大活躍してます。
他にもタジン鍋とか、バウルーとか、無水鍋とか、電気ケトルとか、「一個あると凄く便利!」なキッチン用品は色々有りそうですね。ただ、キッチンの収納は有限なので、あれもこれも全部買うわけにも行きません…
そこで、場所を取らず、1人暮らしの男性に広くオススメしたいのは、スパチュラ(シリコンヘラ)です。

何に使うか

お菓子用のゴムベラなんかと違って、なんと330度までの高温に耐えます。木べらの代わりとして調理にガンガン使うようなアイテムです。

食べ物がごっそり取れる

木べらと比べて最大のメリットは、フライパンや鍋から楽しいくらい綺麗に食べ物をさらえること。洗い物は楽になるし、作ったものを無駄なく食べられるしで一石二鳥。カレーをよく作るような一人暮らし男性は絶対に買うべきです。

匂いが付きにくい

木べらだと、へらに食べ物の匂いが染み付くことがあります。洗いものを溜め込む面倒臭がりの男性にこそ、匂いの付きにくいシリコン製のヘラはとっても便利。料理と菓子作りに併用することもできます。

洗うのが楽

シリコンスチーマー同様、シリコンなので洗うのが楽ちん。料理をよそう時にだけ使うなら、さっと水で洗うだけで大抵OKです。

場所を取らない

これを買うと木べらが要らなくなるので、収納場所の心配はいりません。どうせ混ぜるための何かは必要になるので、ちょっとだけ奮発してスパチュラを買っちゃいましょう。

どれ買えばいいか

幾つかのメーカーから発売されている中で、自分が愛用しているル・クルーゼのMサイズはゴムが硬すぎず柔らかすぎず、大きさも丁度良くて万能に使えます。他メーカーのスパチュラより若干お高いんですが、今ならAmazonで30%OFFなので超おすすめ。

まとめ

スパチュラは万人にオススメできますが、一人暮らし男性には特に便利なアイテムです。フライヤーは買うのに勇気がちょっと要りますが、これは取り敢えず一本買っておいても損はしないんじゃないでしょうか。スパチュラでもっと楽な自炊ライフを!

Javaとスマホ開発の素人がAndroid SDKを触ってみた.初日.

本日,こういうイベントに参加してきました.

上層テスト技術者に贈るAndroid開発入門講座 : ATND

自分はJava分からないし,iPhoneユーザーだし,上層テスト技術者でもないというか社会人ですらない.全てを間違えました.なんというか申し訳ありません….先日買ったちっこいAriaさんと戯れたかったんです….暖かく教えて下さったテスト部の皆様に感謝です.感想と,その後やったことを記録として残しておきます.

午前の部

まずは環境構築.といっても,講師の方がAndroid SDKやらEclipseやらまとめて配布して下さったので,面倒な設定でつまづくことは全く有りませんでした.大変助かりました.自宅の回線環境がだいぶアレ(30〜70kbps)なので,自力で環境構築してたら死ぬところでした….浮いた時間でとりあえずJava基礎文法最速マスター - いろいろ解析日記とかを見つつ,eclipseのショートカットを覚える.至った結論:とりあえずCtrl+Space押しておけ.DDMSでFizzBuzzをやったりしてたら昼に.

午後の部

お題だった,割り勘計算アプリを作りにかかります.Androidの世界は(人工衛星の世界と比べると)組み込みとはとても信じられないようなリッチさで,心底羨ましい….「いいんですか?湯水のように一時オブジェクト作っちゃっていいんですか?やったー!」と,ご馳走を与えられた犬みたいな感じで勝手に(すみません…)コーディング.DDMSでGCが走ってるのを見るだけで喜ぶ有様ですよ.Android Wiki*なんかをリファレンスにしつつ楽しく手を動かす.
アプリは残念ながら完成とは行かなかったのですが,講習を通してEclipseの手懐け方だったり,Java的なお作法だったりも含めて,エンジニアの方々の声を聴けたのはとても新鮮な体験でした.

終了後

鉄は冷めないうちに,ということで,帰ってからもうちょっと自習.まず[Android] Google URL 短縮 API を Android から呼び出してみました - adakodaを見て,短縮URLでちょっと遊んでから,ATNDのAPIを弄ってみる.嵌りどころも無さそうだなーと思ってたら,Java Library for ATND API - ATND4J on SourceForge.JP Web spaceというJava向けのライブラリを発見したので,自分のコードを葬り去り,有り難く使わせていただくことに.

自動import怖い

JavaというかEclipseで一番びびったのは,コピペやらコード補完やらするたびに,必要なパッケージが自動的にimportされていくこと.たとえば

public class Foo extends Activity 

という一文を補完するとき,android.app.Activityを意図したつもりが,実は全然違うパッケージのActivityを選択してた!みたいなことがたまに起きたり.そうすると補完適用箇所の結果は一緒でも,画面外の場所でコードが変わってしまう.まだちょっと慣れませぬ.

ListViewで嵌る

ListViewとListActivity(3)-応用編 - 愚鈍人などを参考に,ListViewのお勉強.GUICSSみたいに流し込んでいく感じで(てきとーな喩えだ).で,よく根本の動作を理解してないまま手を動かしたので,これにド嵌りする.
AndroidのListActivity: おちエンのブログ

HTC Ariaの実機転送でもちょっと嵌る

HTC製の同期アプリ,HTC Syncをインストールしないと,いくらSDK側をアップデートしても転送できない.ついでに,USB接続時の挙動は「充電のみ」「USBテザリング」「外部メモリ」「HTC Sync」から選択可能だけど,これはHTC Syncにしないとダメ.挙動をテザリングに固定していたことに気づかず,しばらくあたふたしていた.

そんな感じで

1日の成果はこんな感じ.気になる単語でOR検索した結果をリストに並べるアプリもどきです.アイコンのクオリティがアレすぎて泣ける.



User Experienceもクソもない動作をしますが,何にせよ色々初めてでもあっさり動くものが出来るってのは面白いなーと思います.自分のスマートフォンで自分の書いたアプリが動くと,なんか愛着湧きますね.

msysgitでssh接続時にid_rsaのパーミッションエラー

環境再構築中に出た症状.msysgitでssh接続を試みたところ,以下のようなエラー.

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0640 for '/Users/xxx/.ssh/id_rsa' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /Users/xxx/.ssh/id_rsa
Permission denied (publickey,gssapi-with-mic).

via.Github-Githubにmsysgitで接続 - 技術情報 - gendosuの企画開発室

パーミッションの取り扱い周りに問題がある模様.chmod 600してもパーミッションが変わらない.んで,まさにこの症状を取り上げているトピックがあったので,

I had the same problem with the latest msysgit 1.7.0.2. The solution is to copy
ssh.exe from cygwin (Computer/Local Disk C/cygwin/bin) into git-bash (Computer/Local
Disk C/Program Files (x86)/Git/bin), then ssh stops complaining about the key not
being protected. So that's a progress.

http://code.google.com/p/msysgit/issues/detail?id=261#c40

このとおりCYGWINssh.exeに置き換える.と,あっさり動いた.なんだこれ….

Hello, Android

「どうせ研究室にしかいない」という理由で昨年秋から自宅の固定回線を解約していましたが,修論も無事に終えて研究室に行く理由が消えた今となっては不便でしかないので,これを機にe-mobileと血の契約を交わしてきました.

買ったのはこれ.テザリング公認のちっこいAndroid2.2端末,HTC Aria
http://www.htc.com/jp/product/S31HT/overview.html

  • 春の引っ越しを機に固定回線から解放されたい
  • メインはあくまでiPhoneだけど,Androidもちょっと弄りたい

という今の状況にぴったり.Dropboxの転送で速攻300万パケットの帯域制限値に達したのは想定外でしたが,用法容量を守ればいい感じに使えそう.テザリング中は本体がほっかほかに温まるので,まだまだ寒い今の季節にもぴったり.Hello, Android