Processing math: 0%

2015年3月24日火曜日

Ctrl-Caps, Alt-Win 入れ替え

Ctrl と Caps, 左右の Alt と Win を入れ替えるためのレジストリです。 Bootcamp 環境で Apple のキーボードを使うにつかってます。
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,07,00,00,00,1d,00,3a,00,3a,00,1d,00,5b,e0,38,00,38,00,5b,e0,5c,e0,38,e0,38,e0,5c,e0,00,00,00,00

2015年3月19日木曜日

やり直しのための信号数学: 第 2 章 正規直交基底とディジタル信号解析

2.1 正規直交基底とは

今度は 4 個のサンプルから成るサンプル列を扱う場合、つまり 4 次元の場合の話。 ここでは N 次元のノルムの定義に \| \boldsymbol{x} \| = \sqrt{ \frac{1}{N} \sum_{i=0}^{N-1}{x_i}^2 } を使う。こうしておくと次元数に関わらず全ての要素が 1 のベクトルは大きさ(ノルム)が 1 として扱えて便利だかららしい。 また、このノルムの定義を使う場合、内積の定義は \langle \boldsymbol{x}, \boldsymbol{y} \rangle = \frac{1}{N} \sum_{i=0}^{N-1}x_i y_i を使う。こうしておくと内積とノルムの一般的な関係 \langle \boldsymbol{x}, \boldsymbol{x} \rangle = {\| \boldsymbol{x} \|}^2 が成り立つ。

とにかく、この前提のもとでは次のベクトルの組 \begin{align*} \boldsymbol{\phi}^{(0)} &= \{1, 1, 1, 1 \} \\ \boldsymbol{\phi}^{(1)} &= \{1, 1, -1, -1 \} \\ \boldsymbol{\phi}^{(2)} &= \{1, -1, -1, 1 \} \\ \boldsymbol{\phi}^{(3)} &= \{1, -1, 1, -1 \} \end{align*} が正規直交基底となる。計算してみればこれらのベクトルのノルムは 1, 相異なる 2 つのベクトルの内積は 0 になる。 この 4 つのベクトルはもちろん適当に選んだわけではなく、"アダマール変換"に関連するものらしい。

2.2 正規直行規定によるディジタル信号分解

何かを測定して 4 個のディジタル値のサンプル \{ f_0, f_1, f_2, f_3 \} を得たとする。 これらを成分とするベクトル \boldsymbol{f} は(もちろん)先の正規直交基底ベクトルの線形結合として表すことができ、 \boldsymbol{f} = F_0 \boldsymbol{\phi}^{(0)} + F_1 \boldsymbol{\phi}^{(1)} + F_2 \boldsymbol{\phi}^{(2)} + F_3 \boldsymbol{ \phi}^{(3)} となったする。ここで F_k (k = 0, 1, 2, 3) は正規直交基底ベクトルとの内積で F_k = \langle \boldsymbol{f}, \boldsymbol{\phi}^{(k)} \rangle (k = 0, 1, 2, 3) \tag{1} から求められる。このように 1 次結合で表すことを「直行展開する」という。この意味深な正規直交基底ベクトルで直行展開することが「ディジタル信号の分解」ということになるらしい。

式 (1) につして k = 0 の場合、 \begin{align*} F_0 &= \langle \boldsymbol{f}, \boldsymbol{\phi}^{(0)} \rangle \\ &= \langle \{ f_0, f_1, f_2, f_3 \}, \{ 1, 1, 1, 1 \} \rangle \\ &= \frac{1}{4} ( 1 \cdot f_0 + 1 \cdot f_1 + 1 \cdot f_2 + 1 \cdot f_3 ) \\ &= \frac{1}{4} ( f_0 + f_1 + f_2 + f_3 ) \end{align*} となる。同様に、 \begin{align*} F_1 &= \frac{1}{4} ( f_0 + f_1 - f_2 - f_3 ) \\ F_2 &= \frac{1}{4} ( f_0 - f_1 - f_2 + f_3 ) \\ F_3 &= \frac{1}{4} ( f_0 - f_1 + f_2 - f_3 ) \\ \end{align*} となる。

2.3 正規直交基底によるディジタル信号合成

自明だが、直交展開した係数がわかれば、 \boldsymbol{f} = F_0 \boldsymbol{\phi}^{(0)} + F_1 \boldsymbol{\phi}^{(1)} + F_2 \boldsymbol{\phi}^{(2)} + F_3 \boldsymbol{ \phi}^{(3)} よりもとのベクトル、つまりもとのディジタル信号を合成できる。これは \boldsymbol{f} = \langle \boldsymbol{f}, \boldsymbol{\phi}^{(0)} \rangle \boldsymbol{\phi}^{(0)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(1)} \rangle \boldsymbol{\phi}^{(1)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(2)} \rangle \boldsymbol{\phi}^{(2)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(3)} \rangle \boldsymbol{\phi}^{(3)} とも表される。この \boldsymbol{f} の各成分 f_k (k = 0, 1, 2, 3) f_k = \langle \boldsymbol{f}, \boldsymbol{\phi}^{(0)} \rangle \phi_k^{(0)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(1)} \rangle \phi_k^{(1)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(2)} \rangle \phi_k^{(2)} + \langle \boldsymbol{f}, \boldsymbol{\phi}^{(3)} \rangle \phi_k^{(3)} となる。( \phi_k^{(n)} はスカラーであることに注意。)

2.4 波形の類似性と相関値

1 章で軽く触れた相関値について再び。ここからは二つの N サンプルのディジタル信号 \boldsymbol{f} = \{ f_0, f_1, \cdots, f_{N-1} \} \boldsymbol{g} = \{ g_0, g_1, \cdots, g_{N-1} \} の相関値を R^{(fg)} = \frac{ \langle \boldsymbol{f}, \boldsymbol{g} \rangle }{ \|\boldsymbol{f}\| \|\boldsymbol{g}\| } と表す。(繰り返しになるがこれは \boldsymbol{f} \boldsymbol{g} のなす角の cos(\theta) と同じ。) これに(この本が使っている)内積、ノルムを代入すると \begin{align*} R^{(fg)} &= \frac{ \frac{1}{N} \sum_{i=0}^{N-1} f_i g_i }{ \sqrt{ \frac{1}{N} \sum_{i=0}^{N-1}{f_i}^2 } \sqrt{ \frac{1}{N} \sum_{i=0}^{N-1}{g_i}^2 } } \\ &= \frac{ \sum_{i=0}^{N-1} f_i g_i }{ \sqrt{ \sum_{i=0}^{N-1}{f_i}^2 } \sqrt{ \sum_{i=0}^{N-1}{g_i}^2 } } \end{align*} となる。

周期関数の一周期分の信号(サンプル値のベクトル) \boldsymbol{f} = \{ f_0, f_1, \cdots, f_{N-1} \} とこれを N 倍した信号 \boldsymbol{g} = N \boldsymbol{f} の相関係数は 1 になるが、定数 C を加えた信号 \boldsymbol{h}: h_i = f_i + C との相関係数は(同じ形の信号なのに) 1 にならない。 これが 1 になるようにするには、各サンプル値からサンプル値の平均を引いたベクトルを使って相関係数をもとめればいい。 (単に \boldsymbol{f} \boldsymbol{g} 波形の震央が 0 になるように調整してから相関係数を求めれば OK という話。)

2.5 相関値の見方

\boldsymbol{R}^{(fg)} = 1 同相
\boldsymbol{R}^{(fg)} > 0 進み位相 ( \boldsymbol{g} が進んでいる)
\boldsymbol{R}^{(fg)} = 0 相関なし (位相が \pm \frac{\pi}{2} ずれている)
\boldsymbol{R}^{(fg)} < 0 遅れ位相 ( \boldsymbol{g} が遅れている)
\boldsymbol{R}^{(fg)} = -1 逆相

2.6 相互相関係数

二つの似た波形についてどれだけ位相がずれているかを評価するには、相互相関係数 \tilde{R}_n^{(fg)} = \frac{ \sum_{i=0}^{N-1} f_i g_{i+n} }{ \sqrt{ \sum_{i=0}^{N-1}{f_i}^2 } \sqrt{ \sum_{i=0}^{N-1}{g_{i+n}}^2 } } を使う。これは n サンプル分を位相をずらしてみた相関係数ということになる。これを n = 0, \dots, N - 1 まで N 個求めてみて、値が一番大きく(理想的には 1)なったときの n が位相のずれ幅。

2.7 自己相関係数

ある信号に周期性があるのか、あるならばその周期がどれだけなのかしりたい場合は  \boldsymbol{f} = \{ f_0, f_1, \cdots, f_{N-1} \} と n サンプルずらした \boldsymbol{\tilde{f}} = \{ f_{0+n}, f_{1+n}, \cdots, f_{N-1+n} \} について自己相関係数 \begin{align*} \tilde{R}_n^{(ff)} &= \frac{ \frac{1}{N} \sum_{i=0}^{N-1} f_i f_{i+n} }{ \sqrt{ \frac{1}{N} \sum_{i=0}^{N-1} {f_i}^2 } \sqrt{ \frac{1}{N} \sum_{i=0}^{N-1} {f_{i+n}}^2 }} \\ &= \frac{ \frac{1}{N} \sum_{i=0}^{N-1} f_i f_{i+n} }{ \frac{1}{N} \sum_{i=0}^{N-1} {f_i}^2 } \\ &= \frac{ \sum_{i=0}^{N-1} f_i f_{i+n} }{ \sum_{i=0}^{N-1} {f_i}^2 } \end{align*} の n を 0 から N-1 まで変化させながら求めてみる。その結果に周期的な極大が現れれば、周期関数であり、その周期がもとの信号の周期になる。

余談

MathJax すげー!と思ってこの本の理解を整理するために書き始めたけど、やっぱり数式打つのが面倒になってきた...

それでも Web の世界で(画像を貼り付けるような面倒で残念な方法をつかったり、環境依存な手段をつかわずとも)まっとうに数式を記述できるようにした MathJax は偉大だと思う。 逆になぜ今まで科学論文から始まった Web の世界にまっとうな数式記述手段がなかったんだろう? Web の世界が急速に成長を始めたころには既にアカデミックなコミュニティはニッチな世界になってたから?

2015年3月13日金曜日

やり直しのための信号数学: 第 1 章 信号数学の準備

本業で必要になって...

1.3 信号数学の予備知識

ある信号 x(t), y(t) を 2 回サンプリングしてサンプル列 (x_0, x_1), (y_0, y_1) を得たとする。 これは 2 次元のベクトル \boldsymbol{x} = (x_0, x_1), \boldsymbol{y} = (y_0, y_1) を得たと考えることができる。 これらの信号の相関、つまりこれらのベクトルの相関を考える。 これらのベクトルの特徴の一つとして大きさを考えることができる。 この大きさの差 d(\boldsymbol{x}, \boldsymbol{y}) = \|\boldsymbol{x} - \boldsymbol{y}\| = \sqrt{(x_0 - y_0)^2 + (x_1 - y_1)^2} がこれらのベクトル、つまり信号の相関を表す量の一つということになる。 (この縦 2 本線の絶対値はノルムといい、N 次元ベクトルのより一般化した大きさに相当する量になる。 ここでは通常の絶対値と同じ定義を使っているが、ノルムの要件を満たせば異なる、より都合のいい定義を使うこともできる。実際、後で違う定義が出てくる。)

さて、この 2 つのベクトルの成す角度もこれらのベクトル、2 つの信号の相関と考えることができる。 (同じ方向を向いていれば完全に相関がある、 \pi / 2 違う方向を向いていれば全く相関がないと考える。) 内積の定義 \langle \boldsymbol{x}, \boldsymbol{y} \rangle = \|\boldsymbol{x}\| \|\boldsymbol{y}\| cos(\theta) より cos(\theta) = \frac{ \langle \boldsymbol{x}, \boldsymbol{y} \rangle }{ \|\boldsymbol{x}\| \|\boldsymbol{y}\| } がこの相関を表す量ということになる。 この量を r と置き、相関係数と呼ぶ。 r が 1 なら完全な相関, 0 なら相関なし、-1 なら負の相関ということになる。

任意のベクトル \boldsymbol{x} を正規直交基底ベクトル { \boldsymbol{e_1}, \boldsymbol{e_2} } の線形結合 \boldsymbol{x} = x_1\boldsymbol{e_1} + x_2\boldsymbol{e_2} として表すには (x_1, x_2) x_1 = \langle \boldsymbol{x}, \boldsymbol{e_1} \rangle \\ x_2 = \langle \boldsymbol{x}, \boldsymbol{e_2} \rangle として求めればよい。

プログラミング言語 C++ 第 5 章

メモ_φ(・_・

第 5 章 C++ を探検しよう : 並列処理とユーティリティ

プログラミング言語 C++ 第 4 章

メモ_φ(・_・

第 4 章 C++ を探検しよう : コンテナとアルゴリズム

  • こんな書き方が!これは捗る:
    vector phone_book = {
      {"David Hume", 123456"},
      {"Karl Popper", 234567},
      {"Bertrand Arthur William Russell", 345678}
    };
  • std::map はキーを大小比較することで目的の要素を探す。std::unordered_map はキーのハッシュ値を使って目的の要素を探す。

2015年3月6日金曜日

プログラミング言語 C++ 第 2 章、第 3 章

メモ_φ(・_・

第 2 章 C++ を探検しよう : 基本

  • これが新しい初期化構文か:
    double d2 {2.3};
  • コンパイラはどうやってコンパイル時に constexpr 関数を実行するんだろうか?クロスコンパイルの場合にはライブラリのオブジェクトファイル内の実装を実行してみることもできないし。インライン関数みたいにヘッダファイル内に実装も書いておくんだろうか?
  • 宣言時に使用する、&、*、[] などの演算子は、宣言演算子と呼ばれる。
  • enum class はメンバ関数を持てる。
  • 確かに: 厳密に言えば、分割コンパイルの仕組みは、言語そのものとは無関係であって、...

第3章 C++ を探検しよう : 抽象化のメカニズム

  • 初期化構文は std::initializer_list 型で受け取る。
  • "ムーブ"ってそういうことか。
  • =delete という関数修飾をつけると暗黙的に作成される関数を削除できる。
  • using を使う typedef の新しい構文ができた。
  • 実際、標準ライブラリのすべてのコンテナは、自身の保持する値の型の名前として value_type を提供する。

2015年3月5日木曜日

プログラミング言語 C++ 第 1 章

値段も厚さもすごいけど、今メインで使っているのが C++ なので買わずにいられなかった。

まずは「第1章 本書の読み進め方」を読んだ。気になった点として:

  • C99 の可変長配列は意図的に C++11 には取り込まれなかった。
  • 1980年の "C with Classes" には既にタスクライブラリがあった(!)が、C++11 で並行処理ライブラリが復活するまで 30 年もかかった!
  • 例外指定が obsolete になってた。
  • (メジャーなコンパイラは実装してないのでお目にかかったことはないけど)外部テンプレートも obsolete になってた。
  • iostream に Norihiro Kumagai さんという日本人がからんでる。(シャープの人?)
  • コンセプトなるものが C++17 で標準入りを目指している。
  • counted_ptr なんてあったの!?
  • Linux の主要部分が C++ で書かれているというのはちょっと違うんじゃないでしょうか?

旧版と比べると(今の所)訳がまっとうになってる感じで安心。

2015年3月4日水曜日

GLSL のコンパイルエラーメッセージにファイル名を含める

ソースコードの頭に #line ディレクティブでファイル名を書いておくと:

#version 430 core
#line 3 "append.fs.glsl"

layout(binding = 0, offset = 0) uniform atomic_uint fill_counter;
layout(binding = 0, r32i) coherent uniform uimage2D heap_pointer;

struct list_item {
 vec4 color;
 float depth;
 int facing;
 uint next;
};

layout(binding = 0, std430) buffer list_item_block {
 list_item item[];
}

in VS_OUT {
 vec4 pos;
 vec4 color;
} fs_in;

void main(void)
{
 ivec2 P = ivec2(gl_FragCoord.xy);
 uint index = atomicCounterIncrement(fill_counter);
 uint old_head = imageAtomicExchange(heap_pointer, P, index);
 item[index].color = fs_in.color;
 item[index].depth = gl_FragCoord.z;
 item[index].facing = gl_FontFacing ? 1 : 0;
 item[index].nex = old_head;
}

glGetShaderInfoLog() の出力にファイル名が出るようになる。

append.fs.glsl(5) : error C1318: can't apply layout(r32i) to image type "uimage2D"
append.fs.glsl(18) : error C0000: syntax error, unexpected reserved word "in" at token "in"
append.fs.glsl(21) : error C0000: syntax error, unexpected '}' at token "}"

#line の次の数値は #line ディレクティブの次の行がソースコード中の何行目に当たるかを指定するもの。