Lua で遊ぶ浮動小数点数

(倍精度)浮動小数点数でいろいろ遊ぶ際に、 Lua が便利なのではないかと思った。以下、特に断らない限り「浮動小数点数」と言ったら倍精度のものを指す。

なぜ Lua を使うのか?

Lua はC言語で実装されていて、数値の扱いについてはC言語と近い挙動を示すと考えられる。C言語と違って累乗の演算子 (x^y) があるのが地味に便利である。

Lua 5.2 以降では、浮動小数点数の16進表記をサポートするようになった。ソースコード中にリテラルで 0x1.fp2 と書けるし、文字列から数値に変換するときに tonumber("0x1.fp2") と書けるし、数値から文字列に変換するときは %a または %A を使って string.format("%a",7.75) と書ける。

あとは、標準ライブラリに足りない機能があったときに簡単にC言語で拡張ライブラリを書ける。

続きを読む

Raspberry Pi で赤外線リモコン

Raspberry Pi の GPIO に赤外線 LED をつけてリモコンとして使おう。

使ったハードウエア

  • Raspberry Pi Model B
    • 手元にあるのは、初代の、プラスじゃないやつ。microじゃない標準サイズのSDカードが刺さる。
    • Arch Linux が入っている。Raspbian だと若干手順が変わると思われる。
  • 赤外線LED
  • 赤外線リモコン受信モジュール
    • 3.3V で使えるもの。
    • Raspberry Pi を送信側として使うつもりであっても、既存のリモコンの信号を分析するには受信モジュールが必要となる。
  • トランジスター、抵抗、配線、ブレッドボードとか

参考にしたページ

ネット上のブログ記事の情報は古い場合があるし、そもそも環境が違って(Raspbian vs Arch Linux)参考にならないかもしれない。ネットの情報は参考程度にして、ソフトウエアのマニュアル等を参照するのが大切である。

作ったもの(ハードウエア)

使う GPIO の番号は選択の余地があるが、適当に GPIO17=出力 (LED), GPIO27=受信 とした。

ソフトウエア的な手順

Linux で赤外線リモコンの信号を送受信するための LIRC というソフトウエアがあるらしいのでそれを使う。

1. LIRC をインストールする

Arch Linux のパッケージになっているのでラクチン。

# pacman -S lirc

2. LIRC をロードする

/boot/config.txt を編集して、 LIRC をロードする。

/boot/overlays/README を参照。例として lirc が書いてあった。

# nano /boot/config.txt
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=27

を書き加える。

lirc をロードするのに modprobe を叩いたり /etc/modules を編集したりは、しない。

(この辺で再起動をかける?)

systemctl start で lircd を起動する。systemctl enable するとラズパイの起動時に自動で起動してくれるはず。

# systemctl start lircd

3. 受信テスト

mode2 コマンドで、受信したものを吐かせる。

# mode2 -d /dev/lirc0

適当にリモコンを向けて、

space (数字)
pulse (数字)

の羅列が出てきたら多分OK。

4. リモコンを登録

irrecord コマンドを使い、リモコンの信号をファイルに記録する。

# irrecord -n -d /dev/lirc0 lircd.conf

メッセージの指示に従う。

途中で、 Enter name of remote と聞かれたので、 homeceiling と入力した。出力ファイル名は homeceiling.lircd.conf となった。

Enter name of remote (only ascii, no spaces) :homeceiling
Using homeceiling.lircd.conf as output filename

個別のボタンを登録する段になって Something went wrong: Cannot decode data といわれ、最後に Try using the -f option. と出てきたので、 -f オプションをつけて再実行した。

# irrecord -n -f -d /dev/lirc0 lircd.conf

homeceiling.lircd.conf ができた。

# cp homeceiling.lircd.conf /etc/lirc/lircd.conf.d/

5. 信号を送る

irsend SEND_ONCE (リモコン名) (ボタン名) で信号を送れる。

# irsend SEND_ONCE homeceiling lighter

Canon 製一眼レフの赤外線リモコン

Canon 製の一部の一眼レフカメラ/ミラーレスカメラには赤外線センサーがついていて、純正もしくは互換品の赤外線リモコンを買うとカメラに触れずにシャッターが押せる。(エントリーモデルの安い機種だと赤外線センサーがついていなかったりするので注意)

純正品のリモコンとしては Canon RC-6 が販売されている。Amazonとかを覗くと、 RC-6 互換のリモコンが山ほど売られている。

動作モードとしては、以下の二つがあり、リモコン側で切り替えられる。

  • 即時シャッター
  • 2秒後シャッター

有線のリモートスイッチと違って、赤外線リモコンを使うには、カメラ側の動作モードをリモコンモードにしなければいけない。

この赤外線リモコンが送る信号は割と単純で、以下のページで解析されている。

www.doc-diy.net :: Canon RC-1 remote control reverse engineered

AVRとかのマイコンと赤外線LEDを組み合わせれば、自作の赤外線リモコンを作ることもできる。上記のWebサイトにも作例がある。

www.doc-diy.net :: DIY Canon RC-1 IR remote control clone

というわけで赤外線リモコンを自作しようかと思ったが、既製品で良さそうなのを見つけたのでそれを買ってしまった。赤外線が結構強力で、2.5mmステレオケーブルを繋げば有線リモコンとしても使える。欠点があるとすれば、電池がやや特殊なことか。

ベルボン株式会社 ツインワンR3-UT

浮動小数点数の関数とオーバーフロー

大抵のプログラミング言語には指数関数 exp や三角関数 sin, cos, tan などの初等関数が用意されている。これらの関数はよく使うので、標準に用意されているというのは合理的だろう。しかし、初等関数の組み合わせで書けるような関数がわざわざ専用の関数として用意されている場合がある。 続きを読む

LaTeX の数式をターミナルで手軽に MathML に変換する

テキストエディタで HTML 文書を直書きしていて、 MathML で数式を書きたいけど MathML 直書きは嫌だ!という時。Pandoc を使えば、ターミナルで手軽に LaTeX 形式の数式を MathML に変換できる。

例:

$ pandoc -f latex -t html5 --mathml
\(\frac{1}{e^z-1}\)
^D
<p><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mrow><msup><mi>e</mi><mi>z</mi></msup><mo>−</mo><mn>1</mn></mrow></mfrac><annotation encoding="application/x-tex">\frac{1}{e^z-1}</annotation></semantics></math></p>

太字の部分が自分で入力する部分である。(^D は Control-D の意)

Haskell で高速なプログラムを書くときに注意すること

Haskell は表現力が高いプログラミング言語だが、気をつけないと非効率的なコードが生成されてしまうことがある。では、どういうところに気をつければ高速なコードになるのか。少し調べてみた。

この記事に書くのは、あくまで原則とかそういうやつなので、コンパイラーの最適化(正格性解析、インライン化、自動ボックス化解除)によっては、自前で工夫しても意味がない、つまり、コンパイラーに任せた場合と同じ結果になるかもしれない。どういう場合に早くなるかはケースバイケースなのだ。 続きを読む

Haskell の Num クラスに対する不満

Haskell には Num という型クラスがあって、足し算とか掛け算の基本的な演算はここで定義されている。標準ライブラリで定義されているインスタンスとしては、 Int, Integer, Rational, Complex a などがある。

一言で言えば Num クラスは環っぽいものに対応するのだが、いろいろとアレな点がある。これを設計した人は、インスタンスとして整数、有理数、浮動小数点数、複素数くらいしか想定していないのではないか。 続きを読む

Picked up JAVA_TOOL_OPTIONS: を擬似的に消す

昔話

その昔、Mac OS X で java コマンドを起動するとターミナルが UTF-8 であってもメッセージがシフトJISで出力されて文字化けしてしまうという時代があった。

java コマンドの起動時に -Dfile.encoding=UTF-8 をつければ出力が UTF-8 になるが、毎回指定するのは面倒くさい。

そんな時、人々は JAVA_TOOL_OPTIONS という環境変数を -Dfile.encoding=UTF-8 に設定したものだ。

そうすれば、確かにメッセージは UTF-8 で出力される。されるのだが…。

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8

という余計なメッセージまで出力される。うるさい。

…というのは過去の話で、最近の Java を Mac 環境で使う分には JAVA_TOOL_OPTIONS を指定しなくても出力が UTF-8 になるので、特に問題はない。(確か、環境変数 LANG を読むはず)

2016年の話

残念なことだが、2016年にもなって、コマンドライン環境で UTF-8 以外のマルチバイトエンコーディング(シフトJISとか)が広く使われている環境が存在する。そういう環境に UTF-8 なターミナル(MinTTY とか)を用意してやっても、デフォルトでは java はシフトJISでメッセージを吐いてくる。したがって、そういう環境で java コマンドのメッセージの出力を UTF-8 にしたい場合は、 JAVA_TOOL_OPTIONS-Dfile.encoding=UTF-8 を指定する必要がある。

まあ、 UTF-8 以外のマルチバイトエンコーディングが広く使われている環境が存在するのは仕方がない。受け入れるしかない。しかし、Picked up JAVA_TOOL_OPTIONS: が出てくるのはなんとかしたい。

このメッセージの出力を抑制できないならば、せめて「見えないように」する方法があるのではないか。つまり、 Picked up JAVA_TOOL_OPTIONS: が印字された後に、空白文字で上書きする…!

つまり、こうだ:

JAVA_TOOL_OPTIONS=$'\r-Dfile.encoding=UTF-8\r                            \r'

$'ほにゃらら' というのは、 bash にエスケープ文字を解釈させる文法だ。この記事に関心を持つような人ならば何をやっているか分かるだろう。

キャリッジリターンとか言ってないで ANSI escape を駆使すれば空行すらなくせるかもしれないが、残念ながらそういうのはキャリッジリターン \r と違い、オプション解釈の際に空白として読み飛ばされない。

真面目な話

ドヤ顔でキャリッジリターンとか書いてみたものの、実際に使ってみると表示が崩れる場合が散見されるので、常用するのはやめたほうがよさそうである。

総合的に考えると、次のようなシェル関数を書いて対応するのがベストかと思われる。(シェルで単独で java を叩いた場合は Picked up … が表示されず、間接的に起動された場合は Picked up … が表示される。)あるいは、シェルスクリプトでラップしてやるという手も考えられる。

export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
function java() {
    env JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS/-Dfile.encoding=UTF-8/}" java -Df
ile.encoding=UTF-8 "$@"
}
function javac() {
    env JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS/-Dfile.encoding=UTF-8/}" "${JDK_P
ATH}/javac" -J-Dfile.encoding=UTF-8 "$@"
}

何をやっているかというと、 java という名前のシェル関数で、「環境変数 JAVA_TOOL_OPTIONS から “-Dfile.encoding=UTF-8” という文字列を削除」「java コマンドに -Dfile.encoding=UTF-8 オプションを渡す」ということをやっている。bash 以外のシェルでは違う書き方が必要になるだろう。

余談

余談だが、ドットネット系のプログラムは、コマンドプロンプトで chcp 65001 をすると出力が UTF-8 になるようだ。UTF-8 なターミナルから MSBuild とか csc とかを叩くときに覚えておくと良いだろう。(Windows の Java も GetConsoleOutputCP で出力文字コードを判断してくれれば良かったのだが…)