2009年3月31日火曜日

bicubic 法

 配列をリサイズしたかったので、Bicubic を使おうと OpenCV で試してみたら、扱いたいデータ型が未対応で、全然使えなかった。そこで、車輪の開発をする事に…。2次元配列は、1次元配列としてアクセスしています。また、boost::multi_array は、やや遅いので却下。
画像で使いたい方は、gil でチャレンジしてみるといいかも?


#ifndef ALGO_BICUBIC_HPP
#define ALGO_BICUBIC_HPP
// BICUBIC 法による配列変換

#include <cmath>

template <class T>
void bicubic_resize(
T* dst, //!< ターゲット
int dwidth, //!< 変換後幅
int dheight, //!< 変換後高
T* src, //!< ソース
int swidth, //!< 幅
int sheight //!< 高
) {
double wfact = static_cast<double>(swidth)/static_cast<double>(dwidth);
double hfact = static_cast<double>(sheight)/static_cast<double>(dheight);

for( int y = 0; y < dheight; ++y ) {
for( int x = 0; x < dwidth; ++x ) {
double sx = wfact * static_cast<double>(x);
double sy = hfact * static_cast<double>(y);
int six = static_cast<int>(sx);
int siy = static_cast<int>(sy);
T value = T();
for( int ry = siy-1; ry < siy+3; ++ry ) {
for( int rx = six-1; rx < six+3; ++rx ) {
double dx = std::abs( sx - static_cast<double>(rx) );
double dy = std::abs( sy - static_cast<double>(ry) );
double wx, wy;
if( dx < 1.0 ) wx = (dx - 1.0) * (dx * dx - dx - 1.0);
else wx = (1.0 - dx) * (dx - 2.0) * (dx - 2.0);
if( dy < 1.0 ) wy = (dy - 1.0) * (dy * dy - dy - 1.0);
else wy = (1.0 - dy) * (dy - 2.0) * (dy - 2.0);
int xo = rx;
if( xo < 0 ) xo = six; //0;
if(swidth <= xo) xo = six; //swidth-1;
int yo = ry;
if( yo < 0 ) yo = siy; //0;
if( sheight <= yo) yo = siy; //sheight-1;
value += src[ yo * swidth + xo ] * wx * wy;
}
}
dst[ y * dheight + x ] = value;
}
}
}

#endif // ALGO_BICUBIC_HPP


参考URL : http://www.geocities.jp/asumaroyuumaro/program/tips/BiCubic.html

2009年3月30日月曜日

あれー?

やっぱ、おかしくね? FeedBurner? Google のアカウントなんかに統合しなきゃ良かった…。ちょーっ、まじですか?Google?

なんか、うさんくさい検索甲子園

 ペナルティを食らった GoogleJapan だが、はっきり言って、最近の検索結果は、以前と比べて良くない。改悪ではないかな?と個人的には感じている。技術系の検索をしていて、本家本元を差し置いて、ちょい解説がトップを占めて、肝心の本家は「日本語検索」をオフにしても、下位に出現するという始末だ。なのにですよ?
 なんで甲子園で検索して甲子園のキーワードのないNHKのサイトがトップの方に出てくるんだよ!kousien? うさんくさくないですか?これは、書かずにはおけません。
 

2009年3月29日日曜日

feedburner&google

 あーん? FeedBurner のアカウントを Google アカウントに統合したとたんに、フィードの更新が全く反応しなくなったぞ!中途半端に買収して飼い殺しにするぐらいなら、Google もやめときゃいいのに・・・テックランチでも、フィードの更新が遅いと文句をたれる記事書いてたけど、Google は新たなサービスを立ち上げるシステムはあるけど、既存のシステムを改善するなり問題点を修正するシステムが無いだろうと思う。これは、ストリートビューの対応や、最近指摘された気の毒なセキュリィティホール(公開されていた文書に埋め込まれた非公開な画像や公開する以前の履歴など)の対応にもあらわれているように思う。
追記:3つ前のエントリでコピペした文書にゴミが入っていたのが、Feedが詰まった原因のような気がする。修正した上で、FeedBurner で Rysync を実施した。

休日

 車無し生活も、すっかり慣れてきました。今日はバスの1日乗車券で小樽の方へ繰り出しました。バスに乗っている途中に、高台から見える海の先に暑寒の山並みが綺麗だったので、思わず俳句を考えてしまいました。

 群青の晴海に浮かぶ雪暑寒

ここんところ、マイブームで日本の古典として、西行法師にまつわる本と、奥の細道を読んだので、感化されたのかもしれません。

しばらく更新は停滞するかも・・・

 仮面ライダー555クリアしました。最終回は、ちょっと意味不明で残念な感じもしましたが、面白かったです。
 今日も OpenGL な日々でした…。この調子だと、しばらく更新は停滞するかもしれません。Silverlight もやらねば…orz...。

2009年3月27日金曜日

mod_pgrest

 もう作る時間は取れそうに無い。本業で2・3のコアなソフトを書かなければならないだろうから…。それと、うちの会社じゃ、こんなもん作っても今のところ猫に小判だ…。使う場面が無い。MVCで言うところのVはブラウザ側でOKだよね?じゃ、汗かいてMは書かなくても、スキーマ定義した段階で、ほぼ終わってるよね?Cの部分は、ストアド・プロシジャか、他の手段を考えてね。

 このコードは、おまけです。

#include <boost/array.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/algorithm/string.hpp>

/// 単語の単数形から複数形へ変換する
/*!
@brief 変換規則は下記
@li 単数形と複数形が変わらない名詞 deer, sheep, fish, squid, moose, salmon, Japanse.
@li 「---」「---e」で終わる名詞 f -> v +es に。scarf, wolf, knife, life, wife. 例外 roof, safe, chief 単純に s
@li「y」で終わる名詞 y -> i +es に。facility, lady, city.
@li 古英語の名詞 man, woman, child, person, foot, tooth, mouse. 不規則
@li 単数形のない名詞 trousers, pants, scissors, pliers, glasses.
@li 「o」で終わる名詞 厳密には +es の場合と +s の場合がある。しかし、+s で統一。
@li 「x」「sh」「s」「z」「ch」名詞 +es に。box, flash, bus
@li ラテンとギリシア語からの名詞 stimulus, phenomenon, axis, nucleus. 不規則
*/
std::string generate_word_unit( const char* word ) {
using namespace boost::xpressive;
static sregex yreg = sregex::compile( ".*[bcdfghjklmnpqrstvwxyz]y$" );
static sregex freg = sregex::compile( ".*(f|fe)$" );
//static sregex oreg = sregex::compile( ".*o$" );
static sregex ereg = sregex::compile( ".*(x|sh|s|z|ch)$" );
static const boost::array<const char*,12> same_words = {
"deer", "sheep", "fish", "squid", "moose", "salmon", "japanese",
"trousers", "pants", "scissors", "pliers", "glasses",
};
// 順番に無頓着なstd::findを利用する事
static const boost::array<const char*,14> ext_words = {
"man", "woman", "child", "person", "foot", "tooth", "mouse", "roof", "safe", "chief", "datum",
"stimulus", "phenomenon", "axis",
};
static const boost::array<const char*,14> exts_words = {
"men", "women", "children", "people", "feet", "teeth", "mice", "roofs", "safes", "chiefs", "data",
"stimuli", "phenomena", "axes",
};
std::string result = word;
boost::to_lower( result );
if( same_words.end() != std::find( same_words.begin(), same_words.end(), result.c_str() ) ) {
return result; // 単数形と複数形が同じ単語
}
size_t pos = std::distance( ext_words.begin(), std::find( ext_words.begin(), ext_words.end(), result.c_str() ) );
if( pos < ext_words.size() ) {
return exts_words[ pos ];
}
smatch match;
if( regex_match( result, match, yreg ) ) {
return result.substr( 0, match.length(0) - 1 ) + "ies";
}
if( regex_match( result, match, freg ) ) {
return result.substr( 0, match.length(0) - 1 ) + "ves";
}
//if( regex_match( result, match, oreg ) ) {
// return result + "s";
//}
if( regex_match( result, match, ereg ) ) {
return result + "es";
}
return result + "s";
}


 というわけで、概要設計を貼っておく。面白いと思ったら作ってくれると嬉しい。自分の考えでは、サービス・イノベーションを起こせるのではないか?と構想してました。

2009年3月26日木曜日

ぱうー

 9巻で、この展開は無理があるだろ…と、ややテンションダウンしてしまった仮面ライダー555ですが、やっぱり、面白いです。この展開にするなら、途中の撮り方をもう少し考えて欲しかった感は残りますが、終わりまで、このまま突っ走るぜーーー!
 「ブレイド」と「響き」も、1巻づつ借りたけど、555は秀逸な感じです。

 boost::asio で pop3 の次回は、boost::spirit の eps_p について書く予定です。

 ここんところ、opengl のコーディングしてます。direct3d は、windows only な上に version が変わる度に、どうして、こうも変化するのか理解不能だけども、性能は良いので悩みどころです。それと並行して、sliverlight の勉強とコーディングもしないとダメっぽい。あと、IISのISAPIかapacheモジュールのどちらかの cgi を書くことになるかもしれない…。全方位かよっ。

 作る予定ではなかった postgresql 用 shortest_path と tsp を作ったおかげで、作る予定だった mod_pgrest は、ぶっ飛ばしてしまいました。つか、もう、こいつを作る時間が取れなくなっちゃったい…。構想の概要設計書だけ公開したら、誰か作ってくれないかな?甘いか…。

2009年3月24日火曜日

小飼弾の 「仕組み」進化論を読んだ

 小飼弾の「仕組み」進化論を読みました。本書は、「仕組み」について掘り下げたものですが、読み終えて不思議な感覚(シンクロニシティ)に包まれました。このブログで問いかけ求めていた解のひとつのあり方が示されているような感覚です。著者の膨大な読書量(本だけに限らない)から熟成されたワインのような味があると思います。
 本書は、政治・経済・文化に携わる文科系の人にこそ読んで欲しいと強く感じます。「仕組み」がテーマですが、情報革命・エネルギー危機・世界恐慌という新たな新世紀を生きるための提言でもあります。内容もわかりやすくてエクセレント!です。
 

2009年3月23日月曜日

boost::asio で pop3 (4)

 今回は、セッション・クラスの破棄についてです。シングル・スレッド感覚で扱える boost::asio ですが、boost::asio::deadline_timer を利用してセッション・クラスを破棄しようと思うと、物凄く難しくなります。結論から言うと、shared_ptr か intrusive_ptr のように参照カウントを管理しないと、破棄できません。
 この難しさは、どこから来るか?と言うと、キューに溜まっている deadline_timer の処理と、通常の送受信ハンドラの処理順序を制御する事ができないところからきます。通信が正常に終了した場合には、deadline_timer のハンドラが残っていますし、キャンセル処理した場合には、これに加えて通常のハンドラがキャンセルされてコールされます。キャンセル時のハンドラの処理順序は規格上不定です。
 よって、気持ちの悪い enable_shared_from_this を利用します。
tr1 だと memory、boost だと enable_shared_from_this.hpp なのでしょうか…。クラスをmixin(侵入継承?)させます。

class hoge : public enable_shared_from_this<hoge> {
...
};

としておいてから、ハンドラの登録時に

boost::bind( // tr1::bind
&hoge::handle_wrote,
shared_from_this(),
boost::asio::placeholders::error
)

とハンドラを指定します。
・・・続く

ついでに libpng, libtiff vc 備忘録

 zlib は、zlibwapi.lib の方を作成してあるので、この前提での作成手順です。
参照 zlib記事 libjpeg記事

libpng
\\projects\visualcXX から、プロジェクトを開く。
zlib をプロジェクトから削除する。libpng.vcproj をエディタで編集し、ZLIB_DLL を ZLIB_WINAPI に変更し、..\..\..\zlib の include パスを場合によって(自前で設定してある場合)は(削除|変更)する。
エクシード・チャージ・・・コンパイル・・・コンプリート。

追記: zlib は、zlib.dll, zlib1.dll zlibwapi.dll の3種類が考えられる。素直に指定するならば、ZLIB_DLL のままで、zlib1.lib をリンクする。

libtiff
これに対して、tiff for windows からダウンロードして、src\tiff\3.8.2\tiff-3.8.2 を上書きでオリジナルのやつに被せる。

copy \libtiff\tif_config.h.vc \libtiff\tif_config.h

を実行し、nmake.opt を編集

#
# Uncomment and edit following lines to enable JPEG support.
#
# 自分の環境に合わせて編集
JPEG_SUPPORT = 1
JPEGDIR = C:/Libs/libjpeg
JPEG_INCLUDE = -I$(JPEGDIR)/include
JPEG_LIB = $(JPEGDIR)/lib/libjpeg.lib

#
# Uncomment following lines to enable Old JPEG support
# (modified IJG JPEG library required, read the contrib\ojpeg\README first).
#
#OJPEG_SUPPORT = 1

#
# Uncomment and edit following lines to enable ZIP support
# (required for Deflate compression and Pixar log-format)
#
# 自分の環境に合わせて編集
ZIP_SUPPORT = 1
ZLIBDIR = C:/Libs/zlib
ZLIB_INCLUDE = -I$(ZLIBDIR)/include
ZLIB_LIB = $(ZLIBDIR)/lib/zlibwapi.lib

...
...
...

#
# Pick debug or optimized build flags. We default to an optimized build
# with no debugging information.
# NOTE: /GX option required if you want to build the C++ stream API
#
#OPTFLAGS = /Ox /MD /GX /W3
OPTFLAGS = /Ox /MD /EHsc /W3 /D ZLIB_WINAPI
#OPTFLAGS = /Zi


そして、nmake -f makefile.vc だーン。

追記:manifest を埋め込む

C:> mt -manifest libtiff.dll.manifest -outputresource:libtiff.dll;2


PS. 仮面ライダー 555: 9巻目にきて、この展開はちょっと無理があるだろ…と、ややテンション・ダウン。 2012/09/13 追記: tiff-4.0.2 では、nmake.opt を修正するだけで、大丈夫のようです。随分簡単になった。

libjpeg vc 備忘録

 ウィンドウズの Visual Studio で、libjpeg をコンパイルするときの手順の備忘録。
必要な作業を簡略化できるので、まずは VC10用のプロジェクトを生成する。
C:\jpeg-9b> nmake -f makefile.vc setup-v10
次に
C:\jpeg-9b>  nmake  -f  makefile.vc  nodebug=1
C:\jpeg-9b>  nmake  -f  makefile.vc  nodebug=1  test

でOK。

win32.mak を利用しているので、DLL 版を作成したい場合は、makefile.vc に対して
# You may want to adjust these compiler options:
#CFLAGS= $(cflags) $(cdebug) $(cvars) -I.
CFLAGS= $(cflags) $(cdebug) $(cvarsdll) -I.
# Generally, we recommend defining any configuration symbols in jconfig.h,
# NOT via -D switches here.

# Link-time options:
#LDFLAGS= $(ldebug) $(conlflags)
LDFLAGS= $(ldebug) $(dlllflags)

# To link any special libraries, add the necessary commands here.
#LDLIBS= $(conlibs)
LDLIBS= $(guilibsdll)

...
...
...

libjpeg.lib: $(LIBOBJECTS)
 $(RM) libjpeg.lib
 link -out:libjpeg.dll /MANIFEST /DLL  $(LIBOBJECTS)
 mt -manifest libjpeg.dll.manifest -outputresource:libjpeg.dll;2
#   lib -out:libjpeg.lib  $(LIBOBJECTS)

として、jmorecfg.h を
//#define GLOBAL(type)  type
#define GLOBAL(type)    __declspec(dllexport) type
/* a reference to a GLOBAL function: */
//#define EXTERN(type)  extern type
#define EXTERN(type)    extern __declspec(dllexport) type

にすればよい。ただし、makefile の作りが元々 DLL を考慮していないので、テストに失敗します。テストしたい場合には、CFLAGS, LDFLAGS, LDLIBS 等の変更を戻して、del *.exe してから行えばよい。

参考URL: http://www.amy.hi-ho.ne.jp/jbaba/jpeg13.htm

追記:コメントが逆だったので訂正しました。

LNK2019 とエラーになる場合は、

extern "C" {
#include <jconfig.h>
#include <libjpeg.h>
};

更に INT32 が再定義されるというエラーに悩まされる場合には、jmorecfg.h に以下の修正を入れて、include する前に #define DISABLE_INT32 というようにする。
#ifndef XMD_H   /* X11/xmd.h correctly defines INT32 */
#ifndef DISABLE_INT32
typedef long INT32;
#endif
#endif

ちなみに、 #define XMD_H をしても良いのだろうけど、影響範囲がパッと見に推定できないので、このようにした。

追記: manifest を埋め込む。
C:> mt -manifest libjpeg.dll.manifest -outputresource:libjpeg.dll;2

とすれば、OK。

2017/10/30: vc10 から link オプションの /MANIFEST がデフォルトでなくなったのでオプションを追記

2009年3月21日土曜日

boost::asio で pop3 (3)

 第3回目まで進んで、タイトルは「boost::asio の勘所」とでもした方が良かったか?と、後悔してます。なかなか pop3 の実装には入れません。前回は路線図を書いてみようという事でしたが、今回は通信における妙についてのお話です。

 async_write で、1024 byte 送信すれば、次の処理では、おそらく 1024 byte 送信された状態で処理が渡されると思いますが、受信に関しては、この事が全くあてはまりません。仮にクライアントとサーバの通信コードを両方とも自分が書いていても、途中の経路におけるルータの都合でパケットが分断されるかもしれないのです。また、相当昔の話になりますが、Flying XMODEM というのが流行った事があります。これは、受信をしたら ACK を返すという処理を、受信する前から先にACKを送信して転送速度を稼ごうというものでした。

 非同期IO処理における難しさの2点目は、指定した通りの送受信結果が反映されているという前提は成立しない点にあります。

 しかし、これらを補うフリー関数(普通の関数)があるので、これらを活用します。async_read, async_read_until 等が相当します。注意しなければならないのは、これらの関数は、指定した位置(状態)までを読むのではなく、条件を満たすまでキューの処理を繰り返すという点です。32 byte 読んでね!と指定したら、32byte以上を読んだ時点で指定した関数へ処理をリレーしますし、CL+LF まで読んでね!と指定したら、CR+LF の組が出現した時点で指定した関数へ処理をリレーします。相手の送信の仕方によっては、きっちり32byte のデータ長や、CR+LFまでのデータを受信するのではなく、次の段階のデータを受信している可能性もあるという事です。このため、async_read_until だけでは足りないと思って作成したのが getuntil です。

・・・続く

2009年3月19日木曜日

クラウドについて述べよというお題

 クラウドについて述べよというお題が出たような気がするので、書いてみます。といっても、たいした事はかけないです。

 ストールマン氏が批判したクラウドは半分当たっていますが、クラウドは何も大手ISPが提供するものだけを指すのではありません。製品名は忘れてしまいましたが、面白いと思った製品にNECのパソコンで、デスクトップをインターネット上に接続して、外出先からミニノートを使ってデスクトップ上のディスクにアクセスできるというものがありました。クラウドの先が自宅のパソコンだった…ってシナリオです。

 クラウド・・・これが指すものは、「通信インフラが整備された事により、デジタル化できるものは場所や距離が関係なくなった」という事だと思います。前に書いた、この投稿のようなものです。言い方を変えれば、ユビキタスなのかもしれません。

 ブラウザで、IEだけが孤立している点と、JavaScriptにおける互換性対策に通常の倍以上のコストをかけているのも虚しい現実で、その経済的損失は、計り知れないものがあると思います。ただ1点だけ、IEにおけるWebDAVの実装は、おかしい部分もあるけれど、firefoxにおけるWebDAVの実装は、更に残念だと思う今日この頃です。WebDAVの実装がまともならば、もっと世界は広がるのに・・・。

 最後に、今、記録媒体に対するパラダイム・シフトが起こっています。SSDや次世代SDカード等の事です。オンメモリで動作するOracleの製品 TimesTen がありますが、こんなもの何の意味があるの?という時代が目前に迫りつつあるのではないか?と感じています。このパラダイム・シフトにより、今までのプログラミング概念が根本から覆る日も近いのではないか?という意識を持っています。そして、この変革は、おそらくクラウドのあり方にも影響をもたらす気がします。通信で取得するよりも、よく使うなら手元に置いとけ的な動きも出てくると思います。クラウドは、今で言うSDカードだったりするのかもしれません。

 Google Gears は、WordPress のメンテナンス画面に対するアクセスを高速化するのに使われている程度で、一般的に浸透しているようには思えません。実装コストが高いので普及していないのだろうと推測しています。これよりも、安価になった高速大容量ディスクにどちらかというとフォルダの同期感覚で同期できて、RESTfulチックにアクセスできるような仕組みが欲しくなるところかもしれません。

2009年3月18日水曜日

boost::asio で pop3 (2)

 すみません、忙しいのと、いろいろとやりたい事があって気分がのりません。なので、ゆるゆると書き散らす事にします(手書きの図をつけようとも思ったのですが、気分がのらない)。
 boost::asio のブロッキングIOを使ったクライアント側のコーディングは、そんなに難しくないと思います。難しいと感じるのは、やはり、その名のとおり非同期IO処理でしょう。この非同期IOですが、直列化(キュー)されているのでシングル・スレッド感覚でコーディングして構わないのに、妙な難しさがあります。同じような処理をする関数なのに同じにできそうで、できない…。こんなジレンマを感じるのではないかと思います。この辺をクリアにするために、鉄道の路線図のようなものを描いてみることをお勧めします。手書きでも、脳内に描いてもOKです。
 boost::asio では、送信・受信の単位で相手からの応答を待つために、処理を分断しなければなりません。例えば、以下のような2つの路線を想定してみましょう。

路線1:送信A -> 受信 B -> 送信 C -> 受信 D -> 送信 E -> 受信 F
路線2:送信G -> 受信 H -> 送信 C -> 受信 D -> 送信 I -> 受信 J

この2つの路線で共通部分の 送信 C -> 受信 D ですが、受信 D に路線の切替機を設置しないことには、異なる関数として実装しなければならないのです。路線1を走っている場合には、「路線1を走っていますよ」という状態変数を保持し、路線2を走っている場合には、「路線2を走っていますよ」という状態変数を保持して、始めて 受信 D の関数にて、分岐ができるようになります。すなわち、受信のコマンドによる分岐以外で分岐するためには、セッションをクラス化する必要があるのです。
・・・続く

ひさびさきたぜ ATL

 まあ、COMやってると、ATL や WTL はソースもオープンで、品質もオープンです。何で俺がATLのバグフィックスせなあかんねん…と思うことしばしばですが、久々に変な現象にぶちあたりました。で、今デバッグしてて、妙なところで ASSERT するから、調べてみたらこんな情報を見つけました。有難いのだが、つっこみ入れさせてもらおう。
m_bAutoDelete の変数は、記法上、見るからに BOOL で、TRUE, FALSE を扱うはずなんですが、
#define DEFERDELETE 2
って何事ですか?ああ、Windows って、WORD BOOL でしたね。こういう場合の変数は、int にしませんか?

2009年3月16日月曜日

dsbl.org 停止

 ハートの拒絶日誌によると、dsbl.org が停止したようだ。利用されている方は、問い合わせを行わないよう速やかに措置した方が良いでしょう。
追記:http://www.dsbl.org/ でも gone と書かれている。このリンクは、どれぐらい持つのかわからない

2009年3月14日土曜日

555にはまる・・・

 うちの坊ちゃんが嫁さんとビデオ屋で借りてきた仮面ライダー555、全然興味が無かったんだけど、ストーリーが面白くて、はまってます…。くっそー、続きが気になって眠れねぇ~

boost::asio で pop3 (1)

 実は、日本SpamAssassinユーザ会に入って活動するにあたり、パーソナル・ユースのスパムよけメーラが、どいつもこいつも気にいらない(その状況は現在も変わっていない)ので、日本語対応のSpamAssassinと絡めて、パーソナル・ユースのものを作成したいと思ったのが、boost::asio で pop3 を実装してみようと思ったきっかけでした。
 何故、空前の C++ ブームというものが起こるか?というと、受託開発型だとソフトウェアを高速化するのに3人月かけるぐらいなら、スペックの高いハードウェアを投資した方が割に合いますが、ロングテールでビジネスするならランニング・コストは安い方が良いからだと思います。それは、さておき、asio の設計は理に適っています。
 一枚のLANカードに一度にアクセスできるのは、ひとつのプロセスでしょうが、マルチスレッドで処理をしても、この制限があるために、結局はリソースの競合を避けるために同期保護を行わなければなりません。ひとつしかないトイレで用をたせるのは、一度に一人だからです。asio では、行列を作って直列に処理をさせます。ただし通信は相手がある事なので、処理できる状態の行列と、処理できない状態の行列(送信待ち、受信待ち、タイマー待ち等)の2つ行列を作成します。こうする事で滞りなく処理ができるというわけです。
 次回からは、実際にコーディングをしてみて、asio ならではの考え方について書こうと思います。ただし、socket プログラミングはやった事が無かったので、細かい構造までは理解していません。

金融不安定性の経済学

 本日もセミナーを受ける予定だったが、急ぎのデバッグが入って、とてもセミナーを受けれる状態ではなくなってしまった。先日の世界危機のセミナーで薦められた本を紹介します。正直、書評できる自信がありません。まだ読んでいません。アマゾンにも本の画像がないようなので、はっておきます。

 ハイマン・ミンスキーさんという、今は亡き経済学者の書かれた本で、世界危機になってから注目を浴びている本らしいです。一味違った読書になるのでは…と、私も期待しています。

第1部 序論(経済過程、動向、および政策)
第2部 経験的事実(1975年、不況とまで落ち込まないまでも深刻であった景気の落ち込み―大きな政府が与えたインパクト
不況ならざるも深刻であった1975年と1982年の景気後退―最後の貸し手の介入が与えたインパクト
戦後の金融不定定性の発生)
第3部 経済理論(理論の展望
現在の標準的理論―ケインズ以後の総合
資本主義経済における価格と利潤
投資と金融
金融取引契約と不安定性)
第4部 制度の動学的運行(資本主義経済での銀行業
インフレーション)
第5部 政策(政策序論
改革に向けての検討事項)
付録A 資金調達構造
付録B 消費者物価と実質賃金

マルチスレッドについて(6)

 よくある事ですが、DEBUG情報を埋め込んで実行すると、マルチスレッドにおけるバグが再現しない事があります。一番簡単なのは、std::cout 等でデバッグ情報を出力する事ですが、これでは再現しないという事もあります。とにかく、手がかりが無い事には、どうしようもありません。Windows で私が使う手のうちのひとつに、OutputDebugString API を利用して、Release版でデバッグを行うというものがあります。あるいは、syslog に出力するというのも良いと思います。マルチスレッドのバグ再現はタイミング命なので、メッセージは短く必要最小限にとどめましょう。
 どこで、それが起こっているか?が問題で、ソースコードの一部をコメントアウトするなどして、問題が起きる場合の組み合わせを把握するようにしましょう。とにかくマルチスレッド絡みのデバッグは心身ともにタフでなければ、やっていけません。問題箇所を絞り込むという作業が大切です。
 問題箇所を絞り込む事ができたら9割方は解決したようなものです。と言っても破綻しないモデルを考えなければならない場合もありますが…。ここからは、想像力が必要となります。コンテキスト・スイッチが、ここで起こったら?を想像します。アセンブラに近いレベルで考えないといけません。よって、高級言語だけでやってきた人には、しんどい作業かもしれません。
 リーダ・ライタ・ロックのデバッグ用に作った、LockTestのプログラムと解説って、いるかな?この話題書くの、ちょっと飽きてきた…。
続くかもしれない

2009年3月13日金曜日

マルチスレッドについて(5)

 そろそろ、概念的な話には飽きてきたと思うので、具体的なデバッグ方法について考えていく事にします。マルチスレッド・プログラミングで、ひどい目にあう可能性が高いのは
  • 同期保護のやり方がまずくて、デッドロックを引き起こしてしまう
  • 同期保護がうまくできなくて、リソースの整合性がとれずに、おかしな挙動をする。
この2点につきると思われます。デッドロックとは、プロセスやスレッド間で、それぞれがロックしているオブジェクトを他がロックしようと永遠に待ち続ける状態を言います。オブジェクト1・2が存在し、処理A・Bが以下の状態が単純な状態です。

処理A:オブジェクト1をロックしている状態で、オブジェクト2のロックを獲得しようと待ち続ける
処理B:オブジェクト2をロックしている状態で、オブジェクト1のロックを獲得しようと待ち続ける

このような事を避けるために、ロックを行う方向を決めるというテクニックがあります。

A -> B -> C -> D -> E -> ...

こうしておけば、デッドロックは生じません。デッドロックが生じるような場合には、デッドロックを検知しないといけないので、そうなると、かなり厳しいです。では、どうすれば良いかというと、ロックを試みる事です(タイムアウト値を決めて、ロックを試行して、失敗すれば何回か繰り返します)。
 デッドロックの場合は、まだ状況を推測しやすいから良いですが、何かおかしな事が起きたらどうすれば良いか?マルチスレッドにおいては、それが起こるタイミングというものが絶妙で、なかなか再現性が難しい場合が多いのでやっかいです。それでも、何か手がかりを得ない事には、手も足もでません。次回は、デバッグについてです。
・・・続く

2009年3月12日木曜日

マルチスレッドについて(4)

 マルチスレッドでリソースを共有するには同期保護が必要なので、逆の考え方をすれば、いかにリソースを共有しないで分離して並列に処理ができるか?という事に重点を置いた方が良さそうです。これが最初にあげた分離化です。これからは、なるべくリソースを共有しないでも解けるアルゴリズムが重要になると思います。
 最初にあげた整合性確保ですが、大域的な視点で並列化というものを考えましょうという意味で、あえて同期保護とは別にしました。なっていない例で私が思いつくのは、Visual C++ のコンパイルです。プロジェクトの依存関係を設定しているにもかかわらず、それを全く無視して並列にコンパイルしやがるからです。CというプロジェクトはBというプロジェクトに依存しているのに、BとCを平気で同時にコンパイルします。何も考えてないだろ!と、突っ込みを入れて笑うしかありません。
 サイト間で連帯するために、ログを直列化して送信するとしましょう。サイトAからサイトBにログを直列化して送信している所へ別のトリガにより同時に並列でサイトAからサイトBにログを直列化して送信しようとすると、おかしな事になります。前者を処理1、後者を処理2として、以下のケースを考えます。

処理1:  サイトAは、サイトBから受信済みのログ番号Nを取得する
処理1: サイトAは、サイトBにログ番号N+1、N+2、N+3と送信する
処理2: サイトAは、サイトBから受信済みログ番号N+3を取得する
処理2: サイトAは、サイトBにログ番号N+4、N+5、N+6を送信する
処理1: サイトAは、サイトBにログ番号N+4,N+5、N+6を送信する

このケースでは、直列化していなければならないログが、重複した上にシャッフルされてしまいます。サイトAの送信処理は、同じサイトへの同時送信は避けて、再スケジュールするといった措置が必要です。
・・・続く

巡回セールスマン問題を解く(5)

 デモ用に使っているDBサーバが、物凄く重たいので確認してみたら、4G積んでいるメモリを全て使い切ってスワップしまくりだった…。なんとなく、gcc の ランタイムのメモリ・アロケータは、だらしないのではないか?と思い。中途半端に終わっていた pg_allocator をまじめに実装した。札幌近辺での shortest_path だと、ノード数が増えるので時間がかかる。しかし、自分のマシンで実行すると一瞬で終了する。???と思ってデモ用のDBサーバを観察してみると、shortest_path 等の実行時にはCPUが100%で、マシンが悲鳴をあげていた…。情報化時代の戦場はウェブなんだよ。ウェブに使うマシンはケチらないで、ちゃんとしたの投資しようよorz...。と思うのだが、ウェブなんて負荷がかからないから、そこら辺の古いマシンで十分でしょという感覚で運用されてしまう。これが現実だ。
 TSPの方は、現在、異なるやり方で、100都市ぐらいだと、一瞬で終わるようになった。まだ少し時間はかかるが、1000都市でも解けるようになった。現在はもう完全に PostRouting という別パッケージとして独立させてしまっている。新しいアルゴリズムは、まだインプリメントしていないが、古いGA(遺伝アルゴリズム)の方は、そのうち公開するかもしれません。新しい方をブラッシュアップして、他との差別化を図っていこうかと思う。こちらまで公開して、自らコモディティ化してもしょうがない。
 

2009年3月10日火曜日

メモリ転送と条件分岐予測

 配列を循環とみなして処理する場合に、メモリ転送によるローテーションを行ってから、リニアにアクセスするのと、ローテーションしないでアクセスするのと、どちらが速いのか気になって、テストしてみた。思いっきり環境依存なので、あまり幸がなさそうなテストではある。

#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/timer.hpp>

template <class ITER>
class circulator {
private:
ITER first_;
ITER last_;
public:
circulator( ITER first, ITER last ) : first_(first), last_(last) {}
ITER increment( ITER i ) const { return ((i+1)==last_) ? first_ : i+1; }
ITER decrement( ITER i ) const { return (i==first) ? last_-1 : i-1; }
};

template <class ITER>
class linearator {
private:
ITER first_;
ITER last_;
public:
linearator( ITER first, ITER last ) : first_(first), last_(last) {}
ITER increment( ITER i ) const { return i+1; }
ITER decrement( ITER i ) const { return i-1; }
};

template <class ITER, class INCREMENTOR>
double rounded_access_test(
INCREMENTOR incr,
ITER s,
int length
) {
double sum = double();
for( int i = 0; i < length; ++i, s = incr.increment(s) ) {
sum += static_cast<double>(*s);
}
return sum;
}


int main() {
std::vector<int> v;
v.resize( 100000 );
std::cout << "v.size() = " << v.size() << std::endl;
for( int i = 0; i < 100000; ++i ) {
v[i] = i % 50000;
}
std::random_shuffle( v.begin(), v.end() );
boost::timer t;
for( int i = 0; i < 100; ++i ) {
std::rotate( v.begin(), v.begin() + i, v.end() );
}
std::cout << t.elapsed() << " sec..." << std::endl;
t.restart();
for( int i = 0; i < 100; ++i ) {
std::reverse( v.begin(), v.end() );
}
std::cout << t.elapsed() << " sec..." << std::endl;
t.restart();
circulator<std::vector<
int>::iterator> circ( v.begin(), v.end() );
double sum = double();
for( int i = 0; i < 100; ++i ) {
sum += rounded_access_test( circ, v.begin() + 50000, 100000 );
}
std::cout << sum << std::endl;
std::cout << t.elapsed() << " sec..." << std::endl;
t.restart();
linearator<std::vector<int>::iterator> linr( v.begin(), v.end() );
sum = double();
for( int i = 0; i < 100; ++i ) {
std::rotate( v.begin(), v.begin() + 50000, v.end() );
sum += rounded_access_test( linr, v.begin(), 100000 );
}
std::cout << sum << std::endl;
std::cout << t.elapsed() << " sec..." << std::endl;
}


結果は

v.size() = 100000
0.077 sec...
0.063 sec...
2.49995e+011
1.139 sec...
2.49995e+011
0.717 sec...

で、ローテーションしてからリニアにアクセスした方が速い。さすがに100000だと、条件分岐予測もあるし、ローテーションしない方が速いだろうと予想していたが、見事に裏切られた。ま、環境やテクノロジが変われば結果も変わりそうだけど、シンプル・イズ・ベストで良いって事だと思った。

しかしなんだな・・・

 ブログの投稿を整理していて思ったけど、Bolgger は、消したはずの残骸が結構残ってたりしますね・・・。あと、俺ってば、もっと寡黙だと思ってたんだけど…orz。

2009年3月9日月曜日

マルチスレッドについて(3)

 今回は、同期保護について書いてみます。トランザクション処理(上)の7.3によると、同時に並行して同じデータを読み書きするトランザクション(スレッド)T1,T2に対して、次の4つに類型されます。
  1. 更新の消失  T2 READ -> T1 WRITE -> T2 WRITE
  2. ダーティリード T2 WRITE -> T1 READ -> T2 WRITE
  3. 非再現リード T1 READ -> T2 WRITE -> T1 READ
  4. 正常 T1 READ -> T2 READ -> T1 READ
具体的に考えてみると、更新の消失では、1枚の似顔絵を一旦、手元にコピーして、T1はモヒカンを書き加えて戻したが、T2は髭を書き加えて戻したので、T1の書いたモヒカンが消失してしまった状態を言います…(余計、わかりにくくなってしまったかも)。2つのトランザクションに対して、正常なのは読取(READ)の組み合わせのみとなります。

 ちょっと難しそうですが、補足すると、こうなります。
  1. 更新の消失  T2 READ -> T1 WRITE (->T1READ) -> T2 WRITE
  2. ダーティリード T2 WRITE (->T2READ) -> T1 READ -> T2 WRITE
  3. 非再現リード T1 READ -> T2 WRITE (->T2READ) -> T1 READ
 非再現リードは、避けようがないじゃないか!と文句をたれたくなるかもしれませんが、これは、T1 が一連のトランザクション処理を行う間に他のトランザクションによって書き換えられたら、一貫性がないよ!という意味になります。トランザクションが分離していれば問題はありません。

 こういうような事をじっくり解説した本は、おそらくトランザクション処理(上)トランザクション処理(下)を置いて他には皆無であり、選択肢が無いと感じています。この本、豚のように厚くて重たくて割れやすい上に書いてある事が一部おかしいのではないか?という代物で、読もうと思ったら拷問以外の何者でもないのですが、他に同じような本がありません。もし、他にあれば推薦して欲しいです。

 脱線してしまいましたが、従って、スレッド間で共有してアクセスする変数は、アクセス境界で整合性を保てるように不整合となるアクセスを保護(ブロック)しなければなりません。カウンタやポインタをスレッド間で共有する場合には、整合性を取れないと、お亡くなりになったり、悲惨な目にあいます。

 スレッド間で共有すべき変数は最小にして、かつ、最短の処理で
  • READ -> 処理 -> WRITE
  • READ -> 処理
しなければなりません。正常なパターンとして、READ -> READ の組み合わせがありましたので、これを応用したパターンが、Reader - Writer - Lock パターンです。複数の読み手か、単一の書き手で同期保護(ロック)をかけるというものです。
・・・続く

boost::multi_index で複合キー

たまたま、multi_index コンテナを使ってみたい局面があったので、お題に乗ってみますた。こうやって考えてみると、c++よりも、vbの方がよっぽど難しいのではないかという気もします。最近、便利なもの使いすぎて、頭が馬鹿になってますorz...

#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>

class program {
private:
std::string country_;
std::string kind_;
public:
program(
const char* country,
const char* kind
) :
country_(country),
kind_(kind)
{
}

const std::string& country() const { return country_; }
const std::string& kind() const { return kind_; }
};

struct country_kind_key : boost::multi_index::composite_key<
program,
boost::multi_index::const_mem_fun< program, const std::string&,
&program::country >,
boost::multi_index::const_mem_fun< program, const std::string&,
&program::kind >
> {};

struct kind_country_key : boost::multi_index::composite_key<
program,
boost::multi_index::const_mem_fun< program, const std::string&,
&program::kind >,
boost::multi_index::const_mem_fun< program, const std::string&,
&program::country >
> {};

struct ck {};
struct kc {};

typedef boost::multi_index::multi_index_container<
program,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique< boost::multi_index::tag<ck>,
country_kind_key >,
boost::multi_index::ordered_unique< boost::multi_index::tag<kc>,
kind_country_key >
>
> program_set;

typedef program_set::index<ck>::type program_ck_type;
typedef program_set::index<kc>::type program_kc_type;

int main() {
program_set programs;

programs.insert( program("US", "マラソン") );
programs.insert( program("JP", "マラソン") );
programs.insert( program("UK", "マラソン") );
programs.insert( program("CH", "マラソン") );
programs.insert( program("US", "100m") );
programs.insert( program("JP", "100m") );
programs.insert( program("UK", "100m") );
programs.insert( program("JP", "400m") );
programs.insert( program("US", "400m") );
programs.insert( program("US", "砲丸投げ") );

BOOST_FOREACH( const program& p, programs.get<ck>() ) {
std::cout << "国:" << p.country() << ",種目:" << p.kind() << std::endl;
}

boost::tuple<const std::string, const std::string> skey("100m","");
boost::tuple<const std::string, const std::string> ekey("100m-", ""); // かっこ悪い

program_kc_type::iterator kb = programs.get<kc>().lower_bound( skey );
program_kc_type::iterator ke = programs.get<kc>().lower_bound( ekey );
while( kb != ke ) {
std::cout << "種目:" << (*kb).kind() << ",国:" << (*kb).country() << std::endl;
++kb;
}

return 0;
}

2009年3月8日日曜日

初滑り


 ぽかぽか陽気に誘われて、スキーに行ってきました。地元の手稲オリンピアです。
 息子は、嫁さんとキッズエリアで、ソリ遊び。エスカレータ・タイプのリフト付き(入場料はかかります)で、3歳ぐらいの子供でも遊べそうです。
私の方は、ハイランドまでゴンドラに乗って、久しぶりに北壁を滑りました。天気も良く、山頂からの眺めも最高でした。

2009年3月7日土曜日

動的平衡

 福岡伸一先生の本は、面白い。「動的平衡」を書店で見かけたので手にとってみた。「ソトコト」という雑誌と「シグネチャー」という雑誌に掲載された記事に加筆したものらしいです。
  • 第1章 脳にかけられた「バイアス」
  • 第2章 汝(なんじ)とは「汝の食べた物」である
  • 第3章 ダイエットの科学
  • 第4章 その食品を食べますか?
  • 第5章 生命は時計仕掛けか?
  • 第6章 ヒトと病原体の戦い
  • 第7章 ミトコンドリア・ミステリー
  • 第8章 生命は分子の「淀み」
という構成で、それぞれが読切物になっていて、読み易いです。第1章では、例えば、飲むと「相対性理論」の知識が得られる記憶を司る物資の入った夢のような薬の話など(相対性理論は本書に出ません)。第6章では抗生物質と耐性細菌の進化による動的平衡、第7章のミトコンドリアは、パラサイト・イブでも有名なミトコンドリアの話が出ます。
 本書のテーマ動的平衡は、生命システムは何十億年とかけて構築された、幾重にも厳重にバックアップ・システムを備えたフォルト・トレーラントなシステムであり、まだまだ人間の科学では及びも付かないような、ある種の神的な深遠な世界であり、謙虚たれ、と訴えているように感じました。

2009年3月6日金曜日

マルチスレッドについて(2)

 協調作業について考えてみることにしましょう。
現段階でのプログラミングでは、シングルスレッドプログラミングが主流です。ステート・チャート図に代表されるように、状態遷移を考慮してプログラムを組む事に慣れていても、協調作業には慣れていないという側面があると思います。

 スレッドを生成するという事は、同時に並行して作業を行うという事です。家を建築するにあたり、土台が完成しない事には、柱を立てる事ができません。プレハブであれば、1階・2階に関係なくパーツを組み立てる事ができるでしょうが、1階部分を先に設置しない事には2階部分を設置する事ができません。

 作業の進み具合によっては、待ち時間が発生してしまうのです。

 自分の作業を進めながら、相手が作業を完了したか確認するタイミングと度合いなどを考え(=設計し)なければなりません。これが地味に難しい。

 通信系のAPIには、IO Completion port と呼ばれるものがあります。これが使いにくいAPI で、通信を指示(データを送信しろ・データを受信しろ)した後に、通信が完了した時のコールバック関数を登録するか、シグナルと呼ばれる信号機のようなハンドルを利用します。指示してから、完了するまでの間を有効に使えるでしょ?というAPIです。ところがもの凄い短時間に通信が完了してしまって、コンセプトをもって設計しないと、何もしようがありません…。

 単純な作業を任せるだけなら良いのですが、この作業が終わったら今度は、あいつ(スレッド)に違う作業をやらせて…などと、コラボレーションの規模を大きくすれば、それだけモデルも複雑になっていきます。場合によっては、協調作業を行うための指揮者(スレッド)を雇わなければならないでしょう。

 マルチスレッド・プログラミングにおいては、設計の段階で構想力が要求されます。

 マルチスレッド化する目的も考えてみましょう。
  1. レスポンスを確保するためのマルチスレッド化
  2. CPUの性能をフルに引き出すためのマルチスレッド化
  3. セキュリィティを確保するためのマルチスレッド化(マルチプロセス、マルチマシン)
大きく分けると、この3つが挙げられると思います。2番目ばかりに目を向けて、カーネルに推移せずSpinCount 休眠する CriticalSection 命みたいに思う人が多いと感じますが、1・3番目の目的においては、カーネル・レベルまで処理が落ちて、スレッドの動作が完全に停止する「ゆとり」処理も悪くはありません。
・・・続く

2009年3月5日木曜日

マルチスレッドについて(1)

 ここんところ、ちょっとテンションが下がってます。が、書くと書いた手前、1回目は、緩い感じでいきたいと思います。
 「Googleを支える技術」の中にCPUに関する記述が見られます。我々の業界では有名なムーアの法則というものがありますが、ここへ来て変革が起こっています。CPUの処理速度はクロックアップによって成立してきましたが、クロックアップするためには、消費電力を大幅に上げなければなりません。この消費電力が地球温暖化等の問題もあいまって、コア数を上げるという方向へ転換しているのです。この本を書かれた西田さんという方は、スーパープログラマという触れ込みで、スーパープログラマって、どんなやねん?とも思うのですが、読んでみて、なるほど、これは調査から推測まで、これだけのものはスーパープログラマでなければ書けないな?という納得の一冊です。これを書く能力は並大抵ではありません。この業界で読んでいない方は、ぜひ手にとってみてください。
 もうひとつは、情報化社会を支える技術として、超大量処理が挙げられると思います。マルチスレッドの処理は、分散処理問題と読み解くこともでき、以上のような要因により、今後、益々重要になってくる概念です。もう、8割型常識になっている気もしますので、今更、何書いてんの?といった感でしょう。
 マルチスレッド・プログラミングの難しさって、どこにあるのでしょうか?
  • 協調作業
  • 分離化
  • 同期保護
  • 整合性確保
といったあたりになるのでしょうか?同期保護と整合性確保は、意味は同じかもしれません。
・・・続く

2009年3月3日火曜日

うぜー

 vc9 の _SCL_SECURE_VALIDATE_RANGE 余計なお世話だぞ、まだメモリにアクセスしたわけでもあるまいに・・・。こちとら、循環アクセスを扱うので、レンジをチェックして挙動を決めたいっちゅうねん。おまえはJavaかよ!そんなチェックいらんねん。なんで、レンジをチェックするのに、いちいち std::distance せにゃならんねん。アホか。

2009年3月1日日曜日

いろいろ

 会社のウェブサーバ、とんだので、アップロードしていた boost::asio 関連の pop3 とか、リーダ・ライタ・ロックに関してとか、無くなってしまいました。という訳で、この辺について書く予定です。本の方は、最近、現代訳や解説のついた古典を読むのがマイブームです。その分、技術書を読む量が減ってます。CMake ですが、「Mastering CMake」という本を買って読んでいます。ウェブ上の情報だけで cmake について、あれこれやっているわけではありません。そのうち、cmake についても、思うところを書いてみたい。
 本日は、鵡川産のホッキ丼(7枚で千円)で、めちゃくちゃおいしかったのだ…。息子とソリ遊びをして疲れた…。息子が小さい時は、嫌がっていたのに成長したもんだ…。来年あたりになれば、スキーもできるだろうか?来週はカヌークラブの総会だ。

雪崩本について

 今シーズンは、まだ1本も滑っていない凄まじい状況(スキーは、テレマークをやります)。そんな中で、雪崩の本の中から、読むならコレという一冊を紹介しましょう。しかし、需要が無いためか、残りの冊数は少ないようです。読んだのは「最新雪崩学」「決定版雪崩学」「雪崩リスクマネジメント」で「雪崩ハンドブック」は読んでいません。
 Amazon の書評では、あまりいい評価ではありませんが、「雪崩リスクマネジメント」がダントツで良いです。理由は、読んでいない「雪崩ハンドブック」を除いて、他の本は感覚的で要領を得ず、表面上の知識ばかりなのに対して、本書は、
  • 第1章 雪崩の基礎
  • 第2章 雪崩の仕組み
  • 第3章 地形
  • 第4章 気象
  • 第5章 積雪
  • 第6章 安定性
  • 第7章 ハザード評価
  • 第8章 ルート・ファインディングと安全移動の様式
  • 第9章 レスキュー
  • 第10章 ヒューマン・ファクター
というように、要因を分離して、それぞれに対して分析しシステマチックに解説しているからです。著者は、積雪のように予測しにくい要因よりも、地形のようなハッキリした要因を先に書いたとも述べています。

グローバル・エコノミーと世界不況への対応というセミナーを受けた

 先日の金曜日は、北海道大学、佐々木 隆生 先生の「グローバル・エコノミーと世界不況への対応」というセミナーを受けました。その中で印象に残った事を…。

 バブルの典型的なパターンでは、ほとんど物価上昇していないのに資産価値は上昇するという(或いは、上昇度合いの釣り合いが不均衡)奇妙な現象が起こるそうです。これの説明を「生産性が向上したために資産価値が上がった」とする経済学があるそうで、経済学のわからない私などは、この説明を聞いて、なるほどーと納得してしまったのですが、これは、ナンセンスだという事でした。
 金利政策においては、物価上昇だけを考慮して金利を決定するのではなく、資産価値の上昇も考慮して金利を決定すべきであるというもので、ピンと来なかったので質問しました。簡単に言えば

資産がもたらす収入/利子=資産価格

なので、金利を上げると資産価格が下落します。この感覚でいけば、アメリカ・グリーンスパーンさんの取った金利政策は間違っていて、資産価格が大幅に上昇している時に物価だけを見て金利を下げたり、逆に資産価格が下落している時に金利を上げたりしたので、バブルの発生と崩壊を助長してしまったという事です。もちろん、物価の上昇を見て金利が決定されていたわけなので、全くダメという話ではなく、これからの金利の決定には資産価格も参考にすべきであるという話です。

 今までのアメリカ(1983年のレーガノミックス以降)は、最後はバブルにより消費を煽る経済活動だったのが、この破綻により、こういう循環はもう当面戻らないであろうという事で、こうなると、一番影響を受けるのが耐久消費財、すなわち、自動車等になります。

 今後の課題として、
  1. グローバル・エコノミーへの適切な国際公共財の供給システム。G8と言わず国際的機関(世界政府的)による協調の構築
  2. 知識基盤社会とイノベーションを背景とする所得配分の不均衡への対処。高所得者層と低所得者層への乖離の解消(中間所得者層の仕事が減っており、乖離の度合いが第1次世界大戦前に逆戻りしている現状がある)
  3. 財政膨張の基盤の上での財政マクロ調整機能の再建。小さな政府と言いながら、第一次世界大戦等の戦時中のような政府活動が一般化しており、このような異常を脱却しなければならない。また、必要な活動に対しては税金のあり方などを考え直さなければならない(必要なものは取る)。鏡の国(貧乏な中国が金持ちのアメリカへ出資する奇妙な構造)の解消
  4. サステナビリティの実現。破綻しない経済活動(消費を無理に煽ってもダメ、地球温暖化にも考慮)
が、あげられていました。

 注意:これらの内容は、私というフィルタを通して加工されています。

swig boost_random 今度はrubyで

 そもそも自分が使わないものを作ってどうすんだ?って部分はありますが、いつかは swig ってみたいと思っていたのも事実です。で、需要の方がサッパリわかりませんが、swig でベースを書いても案外自分の使いたい言語に落とし込む cmake 等の作業の方で、敷居が高いのかもしれない?と思って、今回は ruby してみました。

 CMakeLists.txt の後半 Perl 部分を以下のように書き換えます

FIND_PACKAGE (Ruby)

FIND_PACKAGE (SWIG REQUIRED)
INCLUDE (${SWIG_USE_FILE})

SET (CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES (random.i PROPERTIES CPLUSPLUS ON)
SWIG_ADD_MODULE(boost_random ruby random.i random.cpp)

INCLUDE_DIRECTORIES (${RUBY_INCLUDE_PATH} ${INCLUDE_DIRECTORIES})

IF (WIN32)
IF (NOT RUBY_LIBRARY)
SET (RUBY_LIBRARY "c:/program files/ruby-1.8/lib/msvcrt-ruby18.lib")
ENDIF (NOT RUBY_LIBRARY)
ENDIF (WIN32)
IF (RUBY_LIBRARY)
SWIG_LINK_LIBRARIES(boost_random "${RUBY_LIBRARY}")
ENDIF (RUBY_LIBRARY)


続いて runme.rb です。

require 'boost_random'

print "Uniform_mt19937\n";
mt19937 = Boost_random::Uniform_mt19937.new( 32 );
100.times do
print mt19937.get().to_s + ",";
end;

print "\Exp_necuyer1988\n";
ecuyer = Boost_random::Exp_ecuyer1988.new( 3, 4, 2.0 );
100.times do
print ecuyer.get().to_s + ",";
end;

print "\nNormal_lagged_fibonacci2281\n";
fibo = Boost_random::Norm_lagged_fibonacci2281.new( 50.0, 10.0 );
100.times do
print fibo.get().to_s + ",";
end;

print "\nLognormal kreutzer1986\n";
kreu = Boost_random::Log_kreutzer1986.new( 5, 0.5, 2.0 );
100.times do
print kreu.get().to_s + ",";
end;

 クラス命名規則が煩いな…と思いました。swig だと、いろんな言語を対象にする訳ですが、中には大文字小文字を区別しない言語やアンダーバーを使えない言語もあるかもしれません。

 尚、テストは windows 上の ActiveScriptRuby で行いました。msvc6.0 が必要です。どうしても…という場合は、config.h

#if _MSC_VER != 1200
//#error MSC version unmatch: _MSC_VER: 1200 is expected.
#endif

をすれば動作しますが、ランタイムのアロケータが異なっているために、メモリリークを引き起こしかねないので、やめましょう(ruby の内部構造を知らないので、可能性の話です)。