boost with Autotools

C++言語では boost ライブラリが有志で作成されており, 一部が C++ 言語の仕様に取り入れられているほどである.

しかしながら, あくまで C++ 言語で使用することを想定しているため, GNU Build System (Autotools) で configure スクリプトを作成するには工夫が必要であった.

以下, 筆者が行った作業を列挙してみる.

  1. Autoconf ArchiveThe macros から ax_boost_base の他, 必要なマクロ (ax_boost_xxx をダウンロードし, 開発パッケージの適当な場所 (以下, ./m4 ディレクトリと仮定) に保存する.
  2. configure.acAX_BOOST_BASE と, 必要に応じたマクロ (例えば, boost::iostreams を使うのならば AX_BOOST_IOSTREAMS を記載する. なお, AX_BOOST_BASE は他の AX_BOOST_xxx よりも前に記述する必要がある.
  3. Makefile.amACLOCAL_AMFLAGS = -I ./m4, AM_CPPFLAGS = @BOOST_CPPFLAGS@, AM_LDFLAGS = @BOOST_LDFLAGS@ 及び program_LDADD = @BOOST_xxx_LIB@ を記載する. (xxx は BOOST ライブラリ名)

これで, aclocal && autoheader && autoconf && automake && ./configure とすれば configure スクリプトが出来上がり, make でコンパイルできるようになる. さらに, make dist-xx で, 上記マクロを含んだアーカイブも作成できる.

Msys2 で扱う Mingw の BOOST パッケージでは, 明示的に configure スクリプトにライブラリの場所を提示しなければならないようだ. つまり, コンパイルをするときに ./configure --with-boost-libdir=/mingw64/lib などといったオプションをつける必要がある. これを忘れると, なぜかコンパイラがライブラリの場所を探せなくて下記のようなエラーが表示されてしまう.

  • checking for boostlib >= 1.20.0... yes
  • checking whether the Boost::IOStreams library is available... yes
  • configure: error: Could not find a version of the library!

Mozilla Thunderbird の再設定で躓く

自宅で用いている電子メールクライアントは Mozilla Thunderbird である. 電子メールクライアントであると同時にフィードリーダーであるので、ブログの巡回用として重宝している.

最近になって, Mozilla Thunderbird の調子が悪いので乗り換えを検討してみたが, 電子メールクライアントとフィードリーダを兼ねるツールはそれほどフリーでは出回っていないので, 設定をやり直すことで対処することとなった.

ウェブサイトでは暗号化が必須となりつつあるが, 電子メールクライアントの送受信でも暗号化通信への切り替えが少しずつ進んでいる. 利用中のプロバイダのメールサーバーもフリーウェブスペースが提供するメールサーバーも TLS 対応であり, メールフィルタである POPFileSSL に対応するようになったことから, その設定に改めた.

メールの受信ができたことは確認したので今度は送信の方だが... アカウントを作成しても[送信済みフォルダ]などのフォルダが自動作成されない. 案の定, メールを送付しても送信メールのコピーが保存されないと表示され, 送信はできるものの, 自動コピーが保存されない. それでは困ってしまうので行ったことは... そのような特別なフォルダを作成したことである. 作成後, アカウント設定にて, 当該フォルダを明示的に指定した. これで, 今までどおりの使用感が復活した.

オンライン統計計算機

XREAサーバーが増強されたことを受けて加筆しています. 不要になった部分はあえて見え消しにしています. テキストをそのままコピーすると余計な部分まで取り込む虞があります.

車輪の再発明... というよりも, プログラム作成練習ということで, 統計でよく利用される分布の統計数値表や統計量などを計算するプログラムを作成してみた. 知る人ぞ知る青木繁伸先生が公開されているプログラムのクローンである. 使用したプログラム言語は C++ で, Boost ライブラリを利用した. Boost の開発者が発表した特殊関数計算にかかる近似誤差は, 青木先生が公開している AWK プログラムを直接 C++ に移植したものよりも小さいので, より正確な値が出力されるものと期待できる.

現在間借りしている XREA は, CGI プログラムとしてマシンネイティブなバイナリを利用することが認められている. ただし, 設置者の環境で行ったものをアップロードする必要がある. サーバーの環境を調べてみると, Linux 32ビットLinux 64ビット環境で動いていることが分かったので...

  1. Windwos 用のプログラムバイナリを使うことができない. Linux 用のプログラムを生成する必要がある
  2. 筆者の環境は64ビットアーキテクチャであるが, 32ビット版のバイナリを生成する必要がある.64ビット版のバイナリか32ビット版のバイナリを用意する必要がある.

という問題が発生した.

どうやって対応したか

Windows 10 導入

Windows 8.1 を利用していたが, 保証期間がそれほど大差がない Windows 10 が無償リリースされるのを受け, 重い腰を上げてアップグレードを開始した..., が, アップグレードが中断されてしまい, Windows 8.1 に戻されてしまった. 仕方がないので, アップグレードではなくクリーンインストールできないか方法を探していたところ, Insider Preview がリリースされていたので, そちらを利用することにした. Windows 8 のライセンスは持っていることからインストール中の評価版は正式版リリースと同時に正規プログラムへ更新されるので,
問題は解決したといえる.

OS の更新に付きまとう問題は今のところ起きていない. プリンタもグラフィックボードも正常に動いている. 引き続き, ほかのソフトを更新したときに不具合が出ないかが気にかかる (特に, TeX や Perl, MSYS のからみ)

msysからカレントフォルダをexplorerで表示

プログラムを書くときに msysemacs を利用しているところだが, ときどき, エクスプローラーからフォルダの内容を表示させたくなることがある. Cygwin なら cygpath コマンドがあるが, msys にはそのようなコマンドが存在しない. しかしながら, カレントフォルダを表示するコマンド pwd にオプションが設定されていることに気付いた. いろいろ試してみた結果, 次のとおりにすれば目的を達成できることが判明した.

explorer file:///`pwd -W`

Perlの更新

Perl は文字列処理に優れたプログラミング言語で, 作者の Larry Wall によれば, もともとは pearl (真珠) という名称にする予定であったが, すでに同名のプログラミング言語があったことに気づいたため現在の名称に変更したとのことである. しかしながら, 後追いで, practical extraction and report language とか pathologically eclectic rubbish lister の頭文字であるという意味を与えた

なお, プログラミング言語を指すときは Perl と先頭を大文字で表記し, Perl で書かれたプログラムを処理するもの (ランタイムコンパイラ) は perl と先頭を小文字で表記する. よって, Perl で書かれたプログラムを perl で処理するという言い方をする.

さて, Perl にはよく使われる処理をまとめたモジュールが公式サイトで配布されているが, これらを個別に更新するとなるととんでもない手間がかかってしまう. そこで, まとめて更新する手段を探していたところ, MASのページに記載があったので引用させていただく. コマンドラインから以下のとおり入力するだけである.

perl -MCPAN -e "CPAN::Shell->install(CPAN::Shell->r)"

標的型攻撃メールが届いた

最近は標的型攻撃メールが大流行しているらしい. まさか自分には届くまいと思っていたが, ついにメールが届いてしまったのでさらしあげてみる. なお, 私のメールアドレスにつながる情報については伏せておく.

エンコードの都合でわかりにくいが, メールの件名は 【再送】Re:問い合わせ となっている. しかしながら, ここ最近は何かを問い合わせをした記憶はない.

Return-Path: <james.elsass@yahoo.com>
Delivered-To: XXX@XXX.XXXX.XXX
Received: (qmail 21821 invoked by uid 89); dd Nov 2013 HH:MM:SS tz
Received: from unknown (HELO yahoo.com) (yyy.yyy.yyy.yyy)
  by XXX.XXXX.XXX with SMTP; dd Nov 2013 HH:MM:SS tz
Received-SPF: none (XXX.XXXX.XXX: domain at yahoo.com does not designate permitted sender hosts)
To: <XXX@XXX.XXXX.XXX>
From: <james.elsass@yahoo.com>
Subject: =?iso-2022-jp?B?GyRCIVo6RkF3IVsbKEJSZTobJEJMZCQkOWckbyQ7GyhC?=
MIME-Version: 1.0
Reply-To: <XXX@XXX.XXXX.XXX>
Date: WWW, dd Nov 2013 HH:MM:SS tz
Content-Type:text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit


お世話になります。

先日お知らせしたウェブサイトの情報をお送りします。

ご確認ください。

-------------------------------
http://tr.im/xxxxx
http://qr.net/XXXX
-------------------------------





-----------------------------------
Source:James M. Elsass

Windows 8 で IPv4 を IPv6 に優先して使用する方法

プロキシ型ソフトウェアの一部にあっては IPv6 アドレスに対応していないものがあったりする. 歴史ある(≒古い)ソフトウェアにはよくある話だ. メールの自動分類ソフト POPFile にあってはインターフェースにアクセスするために localhost という URL を用いるのだが, アドレスを解決した結果, IPv4 アドレスの 127.0.0.1 ではなく, IPv6 アドレスの ::1 と解釈されてしまうとエラーになってしまう.

解決方法を探していたところ, ぼくんちのTV 別館に解決方法が提案されていたのでそれを利用してみた.作業が自動化できるようにバッチファイルにしておく. 変更時には管理者権限が必要 (設定の確認だけなら一般ユーザの権限でよい).

IPv4 優先にする

@echo off

REM 変更前設定確認
netsh interface ipv6 show prefixpolicies

REM 設定作業
netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 50 0
netsh interface ipv6 set prefixpolicy ::1/128 40 1
netsh interface ipv6 set prefixpolicy ::/0 30 2
netsh interface ipv6 set prefixpolicy 2002::/16 20 3
netsh interface ipv6 set prefixpolicy ::/96 10 4

REM 変更後設定確認
netsh interface ipv6 show prefixpolicies
pause

IPv6 優先に戻す

@echo off

REM 変更前設定確認
netsh interface ipv6 show prefixpolicies

REM 設定作業
netsh interface ipv6 set prefixpolicy ::1/128 50 0
netsh interface ipv6 set prefixpolicy ::/0 40 1
netsh interface ipv6 set prefixpolicy 2002::/16 30 2
netsh interface ipv6 set prefixpolicy ::/96 20 3
netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 10 4

REM 変更後設定確認
netsh interface ipv6 show prefixpolicies
pause

桁落ち

桁落ちという言葉をご存知だろうか. 絶対値が非常に近い数同士の加減算で有効桁数が少なくなってしまうことを桁落ちいう. 例えば, 円周率とネイピア数の差について, 有効数字を 3 桁として計算すると次のようになる.

3 . 1 4 ? ?
- 2 . 7 2 ? ?
0 . 4 2 ? ?

この例では, 有効桁数が 3 桁から 2 桁に減っている. このようなことは, プログラム上の計算でも起こりうる話だ. ここまでは, 以前に仮平均を用いた平均と分散の計算でも触れた話だ.

さて, 桁落ちを回避する方法に一般論は存在しない. むしろ, 回避できるケースが珍しいというのだ. 桁落ちを回避できるケースとして, 二次方程式の解を求める方法を考える.

二次方程式 ax2+bx+c=0 (a≠0) における解は, (-b+√(b2-4ac))/(2a) と (-b-√(b2-4ac))/(2a) の 2 つである
(平方根の底が 0 に等しいならば重解となる). 問題は, 4ac の絶対値が b2 と比べて非常に小さい値になるときである. この場合, b>0 のときは-b+√(b2-4ac) の精度がかなり落ちてしまうので, 結果として, 得られる解の精度も落ちてしまう. これを回避する方法として, 次の 2 つの考え方が知られている (計算の内容はほぼ同じ).

  1. もう一方の解 (-b-√(b2-4ac))/(2a) の精度はそれほど悪くならないので, 方程式の解と係数の関係を用いた次の計算を行う. α=(-b-√(b2-4ac))/(2a) とし, もう一方の解を β とすると c/a=αβ となることを利用し, β=c/(αa) を計算する.
  2. 分子を有理化して -2c/(b+√(b2-4ac)) を計算する.

このように, 非常に近い値同士の差を計算しないように式変形することが, 桁落ちを回避する根本的な手段となる.

さて, ここからが本題. 同一の二項分布 (母比率 π) に従う母集団から独立に n 個のサンプルを取り出したとき, そのすべてが陰性であったとする. このときの母比率 π の100(1-α)%信頼区間は [0, 1-α1/n] となる (大多数の文献では, サンプルに陽性のものと陰性のものが少なくとも 1 つずつある場合と処理を分岐しなくてもすむように, [0, 1-(α/2)1/n] としている. 本記事の主題ではないが, 指摘されそうな点であるので紹介しておく).

ここまでの前振りから想像できるかもしれないが, 非常に大きな n においてはα1/n の値は 1 に限りなく近い値となる. この値と 1 の差をとると, 桁落ちが発生してしまうため, コンピュータでは 0 に等しいという結果になってしまう. この計算において桁落ちを回避したいというのが本題である. 累乗が絡む計算において, 底はネイピアの数にしておいたほうが都合がいいことが多いと思うので次のように変形しておこう.

1-α1/n = 1-exp(ln(α))1/n = 1-exp(ln(α)/n)

t=-ln(α)/n とすれば, t がごく微小な正の数のときを考えればよいことになる.

以上を整理すると, 非常に小さな正の数 t に対して, 1-exp(-t) をなるべく高い精度で計算する方法があればぜひ教えてほしい.

プログラムソースの解読

仕事でプログラムを偶に書いているのだが, 他人が書いたプログラムを参考にさせてもらうことも多々ある. しかしながら, 書き方が必ずしも自分にとって見やすいものではないことがある. そういうときは, プログラムソースの整形をすることと, 予約語 (キーワード) を色分けすることで見やすくなることがある.

プログラムソースの自動整形は別途考えることにして, 今回は, 自動で色分けをしてくれるツールを紹介する. google-code-prettify は, HTML 内に書かれたコードを色分けしてくれる JavaScript と CSS で色分けしてくれるものだ. どのプログラム言語を使用しているのかは google-code-prettify が自動で判定する. 実際に使用するときは pre 要素に特定の属性を指定して, あらかじめ特定の文字を実体参照に置き換えたものを記述すればよい. UNIX や MSYS では, 次のようなコマンドを利用すれば実体参照に置換できる (B シェルの場合).

for i in *;
 do \
  cat $i | \
  sed -e 's/&/&amp;/g' | \
  sed -e 's/>/\&gt;/g' | \
  sed -e 's/</\&lt;/g' > $i.txt;
 done