高解像度インタラクティブ版Tweet前回に引き続き今回もProcessingによる日本全国コンビニ店舗分布地図について書いてみる。前回は大きさが固定された地図で拡大・縮小や移動ができなかったので、高解像度インタラクティブ版として、それをできるようにしてみた。日本地図がPNG画像なのでこれをベクタ画像に変更する。フォーマットはSVGだ。前回と同様に「カビパン男と私」で提供されている日本地図のSVGファイルを若干加工して利用させてもらった。次にこのSVGデータをProcessingで利用する方法について述べる。」にもSVGの利用方法(processing.candy.*)が書いてあるのだが、実はここに書いてある情報は古くて現在では使用できない。現在では、PShapeを使ってSVGを利用する。loadShape("japan.svg");こんな感じだ。y)座標に表示するにはdraw関数内で以下のように記述すればいい。y);詳しくはProcessingのリファレンスに書かれているので、下記のソースコードなどを参考にして調べてみて欲しい。これでSVG画像が利用できるようになったので、今度はこれを使って、マウスの左ボタンのドラッグで平行移動を行えるようにしてみる。やり方としてはmouseDragged関数を使う。移動したピクセル分だけ画像も移動する。mouseDragged関数内で移動分のオフセットを変数に入れるようにし、上述のshape関数でオフセット分だけ移動した位置に描画すればいい。次に画像の拡大・縮小を行う。マウスの右ボタンのドラッグで操作する。マウスを上に移動すれば拡大、下に移動すれば縮小だ。SVG画像の縮小・拡大はscaleメソッドを使う。上記の例で元の画像を1.5倍にしたければ以下のようにする。mapShape.scale(1.5);scaleメソッドによる拡大・縮小は画像の位置やそのオフセットなどもちゃんと正しい位置になるようにしなければならないのだが、それらについてはソースコードを参考にして欲しい。上記はSVG画像による日本地図の描画について説明したが、コンビニデータの描画についても位置のオフセットと拡大率・縮小率で行うことができ、Placeクラスのdrawメソッドをちょっといじればいい。最初に全部のコンビニを表示してしまうと分布が解りづらいので、今回はセブンイレブンとローソンのみを最初に表示するようにした。コンビニの表示・非表示はコンビニ名をクリックすることで切り替えることができる。here.以下にソースコードを示しておく。Processingによる情報視覚化手法」を読んでみたのだが、Processingの情報処理とその視覚化がとても興味深いものだった。そこで、日本地図を使って何らかの情報を視覚化したいと考え、それならば全国に存在するコンビニ店舗の分布を調べてみようと思い、Processingで作ってみることにした。因みに以前にも「Processingで分子動力学計算」や「Processingを使ってWebカメラを監視カメラにする」などのブログ記事を書いているように、プログラミング言語Processingはビジュアル関連で広範に応用でき、そのポテンシャルはとても大きい。コンビニの店舗情報が必要なので、gooのコンビニ店舗検索を利用し、ここから住所情報を得ることにした。一度に検索できる件数は5,000件までなので5,000件以上存在するコンビニに対してはPythonで都道府県ごとに検索してマージした。データはHTMLで書かれているのでPythonのre.findallのパターンマッチを使って一気に必要なデータに変換した。MapsのHTTPリクエスト経由のジオコーディングを使って住所情報を経度・緯度に変換した。この辺もPythonを使えばちょちょいのちょいだ。以下のAPIを利用する。http://maps.google.com/maps/geo?q=住所情報&output=json&sensor=false&key=APIキーただし、変換は1日につき15,000件の制限が掛かっているので4万件以上ある住所情報を取得するには3日かかることになる。IPアドレスによる制限なので別のIPを使えば問題ないようだ。日本地図上にデータを表示するためには、経度・緯度情報からXY座標に変換する必要がある。日本地図は国土地理院によるとユニバーサル横メルカトル(UTM)図法が使われているらしい。簡単に言うと世界地図でよく使われているメルカトル図法の赤道に合わせている中心線を6°ごとの経度線に合わせて作成する方法らしい。そのための変換関数をPythonで以下のように作成した。本当は縮尺の微調整が入るようなのだが、今回はそこまで厳密にする必要はないのでその辺は省いた。y以下に、作成したデータの一部を示しておく。データはタブ区切りで、先頭からコンビニID、店舗名、X座標、Y座標になっている。ネットワーク経由で経時的にデータを取得する場合、最初にデータ数を知る必要があるため先頭行に全データ数を記述している。0.134899作成した座標データを表示させるための日本地図だが、「カビパン男と私」というサイトの地図データを利用させてもらった。ここの静止画データをペイントソフトで少しだけ加工してできあがりだ。必要なデータは全て揃ったので、ここからProcessingを使っての視覚化作業になる。言っても、前述の「ビジュアライジング・データ」の6章「散布図」を参考に作成したのでそれほど苦労するところはなかった。詳しいことは書籍を参考にして欲しい。日本地図の画像と座標データのスケーリングについては、日本の東西南北の大ざっぱな位置から大体のスケールを求めてあとは手作業で修正した。以下が作成したプログラムになる。ProcessingはJavaアプレットにエクスポートする機能があるので簡単にウェブに貼り付けることができる。プログラムの使い方だが、最初は全てのコンビニの店舗が表示されている。左上のコンビニ名をクリックすることで表示・非表示を設定できる。データ数が多いのでどうしても店舗が重なってしまうが、そのあたりは表示・非表示を切り替えて対応して欲しい。here.コンビニデータについて。使用したコンビニを店舗数を含めて以下に挙げておく。全ての店舗を合わせると44,447店舗となる。今回作成したデータで正しく位置情報を取得できなかったものについては省いて使用したので、実際に地図上に表示されているデータは若干少なくなっている。今回のプログラミングはなかなか楽しいものだった。コンビニ店舗情報を視覚化することで、セブンイレブンは店舗数が一番多いが四国や東北北部には店舗がなく都市型だとか、ローソンは地方にも比較的広がっているのだとか、店舗数が少ないコンビニは地域密着型なのだろうとか、いろいろ見えてくるのが面白い。Processingはもっと認知され使われてもいいのではないだろうか。追記(2009/12/14):今回はgooのコンビニ店舗検索に載っているコンビニのみを扱ったのだが、コメントで他のコンビニについても言及されたので、セイコーマートとセーブオンの2つのコンビニについて追加してみた。所在地情報はコンビニまっぷから取得した。追記(2009/12/25):地図の平行移動や拡大・縮小ができる高解像度インタラクティブ版を作成してみた。最後に作成したソースコードを示しておく。プログラミング2009年12月12日土曜日CUDAで作成した分子動力学計算プログラムを書き直してみたTweet以前に、はじめてのCUDAプログラミングで分子動力学計算というブログ記事を書いたことがある。最近このなんちゃって分子動力学計算(MD)プログラムのソースコードを読み直してみたのだが、かなりひどい。「CUDAプログラミング」でググってみると、この記事が2番目にくる。こんないい加減なコードを参考にされたら読んだ人にも迷惑が掛かるので修正することにした。それほどCUDAに慣れているわけではないが、前回のコードよりはましだと思う。それにしてもコードの内容がひどい。意味もなく__syncthreads()が入っているし、複数のスレッドから同じグローバルメモリに書き込みしてるし、レジスタを活用してないし、計算の順序は非効率だし、ダメダメだ。Profilerで関数のパフォーマンス測定を行った。因みにこのプロファイラはCUDAプログラミングツールキットに含まれているもので、CUDAでプログラミングを行うには必須だと思う。使い方は簡単で、Windowsであればcudaprof.exeを実行して、FileメニューからNew...を選び、プロジェクトの名前と場所を設定して、実行するCUDAプログラムを指定するだけだ。引数が必要ならそれも指定しておく。デフォルトでは4回実行され解析される。それぞれの関数がどれだけ時間がかかったのかプロットされるので、どこがボトルネックになっているのか一目瞭然だ。予想していた通り、Calc関数が全体の99.8%を占めていたので、ここから修正を行った。iとjを使っていたループをjだけにした。iはスレッド数で分割されていたが、ブロックと合わせてそれを消した。次に、jのループ内で不必要にグローバルメモリにアクセスしないようにした。chg[i]というグローバル変数はループ外でローカル変数に入れてそれを使うようにする。あとは、できるだけ除算などの演算を減らすようにした。次に、系全体を中心に戻す関数があるのだが、中心座標を求める部分はホスト側の関数で実装し、系全体を戻す関数のみをCUDAの関数とした。この処理は毎回やらなくてもよいものなので、指定したステップ毎に1回行うようにした。今回は100ステップに1回としている。全体の処理時間から見れば無視しても良く、頑張ってすべてGPUで処理する必要はないと考えた。全体のエネルギーを求める計算を見直してみた。ここは酷くて、前回のコードではCalc関数ごとに全エネルギーの和を求めるという訳が分からないことをしている。そこで、全エネルギーを求める部分の関数を別に書き、さらに並列リダクションを実装した。今回の実装もこれを参考にさせてもらった。数千個程度の粒子数であれば、デバイスからのメモリコピーを考えてもホスト側で計算させてしまう方が速いかもしれない。一応1024個でスイッチするようにしてあるが、もっと大きな値で良いと思う。以下に実際の処理速度の結果を示す。テストデータとして4,139個の粒子数を持つデータを用意して、それを100ステップ計算させた。以前書いたC++のプログラムは307.1秒かかっている。前回のCUDAプログラムで35.2秒、今回のコードが6.6秒だった。C++と比べると46.2倍、前回のCUDAプログラムと比べても5.3倍高速に動作した。最後に、今回作成したソースコードを示しておく。コンパイル方法や実行方法は前回の記事を参考にして欲しい。構造体を格納したSTLコンテナに対してソート・探索・削除などのアルゴリズムを適用するTweetC++に慣れている人にとっては当たり前のことかもしれないけど、あまりC++に親しんでいない場合、構造体を格納したSTLコンテナに対してアルゴリズム<algorithm>を有効に活用していないかもしれない。そこで、構造体を格納したvectorなどのSTLコンテナでソートや探索、削除などのアルゴリズムの利用方法を書いておく。};上記のような構造体はよく見かける形だと思う。構造体Aに整数型変数のnとポインタ型変数のpがあり、例えばnに配列の要素数、pにその配列を確保したりする。いった構造体を以下のようにvectorなどのSTLコンテナを使って格納することは多々ある。A_list;これで構造体Aをコンテナに格納できるわけだ。ところで、STLコンテナを使用する一つの理由として便利なアルゴリズムが利用できることが挙げられるだろう。sortやfindなどの定番のアルゴリズムは、それほどC++を利用していない人でもSTLを使ったことがあるのであれば知っていると思う。これらはとても便利だが、上記の構造体を入れたコンテナに対して以下のようには利用できない。A_list.end());当たり前のことだが、どのような基準でソートするのかコンパイラには分からないからだ。どのような基準でソートさせるのかを関数オブジェクトを使って教えればいい。因みに関数オブジェクトとは、operator()が定義されているクラスのことだ。構造体Aのメンバ変数であるnを基準に昇順にソートさせたいとする。その場合は以下のような関数オブジェクトを作って、sortアルゴリズムの第3引数に渡せばいい。LessAn());たったこれだけだ。他のアルゴリズムに対しても基本的には同じように関数オブジェクトを使えばいい。探索(find_if)や削除(remove_if)、繰り返し処理(for_each)などを使ったアルゴリズムの利用例を以下に挙げておく。1から30までのランダムな要素数nと0から29までのランダムな要素の配列pを持つの構造体Aを10個作成してvectorコンテナA_listに格納した。それに対し複数のアルゴリズムを適用した出力結果を以下に示している。指定の数値を要素として持つ構造体Aは見つかりませんでした.以下、ソースコード。Engineメッセージボード*当ブログに関する意見や要望などにお使いください。Googleアカウントでログインすることで書き込みができます。Twitterへの送信を同時に行うこともできます。ストリートビューで散歩*Googleマップのストリートビューを利用して散歩をするWebアプリです。ストリートビューとマップを分割してマーカーを視界タイプに変更することで使いやすくしてあります。APIを利用したグラフ・チャート作成ウェブアプリです。クリック一つで簡単にグラフを作成できます。ブログ記事への貼り付けなどにどうぞ。OpenIDテスト*OpenIDによるログインのテストを行います。mixiであればクリック一つで、他のOpenIDアカウントであればそのURLを入力することでテストできます。一言コメント表示機能付きです。HTML文字変換*テキストで使われているHTML特殊文字をウェブで表示できるようにするための文字変換ウェブアプリです。プログラムのソースコードなどをブログ記事に貼り付けるときなどに便利です。短縮URLチェッカー*フィッシングサイト判別機能付き短縮URLチェッカーです。テキストボックスに変換したいURLを入力すればbit.lyの短縮URLが表示され、bit.lyの短縮URLを入力すればもとのURLが表示されます。展開されたURLがリンク付きで表示されますが、もしフィッシングサイトの疑いがある場合は警告が表示されます。Trendsの急上昇ワードをランキング順に表示します。Googleでのキーワード・画像検索やWikipediaによる用語の説明もあります。※GoogleがAPIの提供を終了したため、現在停止中です。自己紹介noxゲームを楽しむだけの余裕と感性は失いたくないnoxです。