延期と四十路

 クイズ番組の『アタック25』で、『エヴァンゲリオン』の作者を問う問題が出題された。いうまでもなく映画の宣伝であるが、緊急事態宣言で上映が延期された。この空振りぶりがいかにもエヴァンゲリオンらしい。製作者たちには申し訳ないが、私の中ではエヴァンゲリオンにはひどいオチがつきものだということになっている。
 ひどいオチといえば、『金曜ロードショー』も同じであり、三週連続でエヴァンゲリオンである。アタック25以上にひどい空振りである。
 これ以上の空振りはないと思うが、エヴァンゲリオンなので今後も何が起きるか分からない。
 ところで、エヴァンゲリオンといえば、1997年の夏の『もののけ姫』との競争が思い出される。あの夏高校生だった我々も、今や40歳前後である。おそらく今度の映画もその40歳前後がメインターゲットであろう。映画館で周りを見ると40歳がたくさんいるとか、そういう光景が見られるんだろうか。それとも親子連れで見に来るんだろうか。いや、親子連れはないだろう。エヴァンゲリオンといえば主人公たちの家庭環境の悪さである。子供に「逃げちゃだめだ逃げちゃだめだ」とか言ってほしくはない。

棋譜中継

 将棋の棋譜中継にはFlashが用いられていたが、Flashそのものがサポート終了になるという問題があった。このことについては何度かこのブログで触れた。
 そして一昨日、マイナビ女子オープンの中継があった(https://book.mynavi.jp/shogi/mynavi-open/result/14/mynavi202101080101.html)。見事にJavaScriptに移行されていた。
 ありがたや。

三色の領域

 研究するにあたり、私は図を多用する。とにかくいろいろとプロットをする。今回、こんな図をプロットすることができた。

f:id:tihara:20210104174209p:plain

 三次元の空間が三色の領域にきれいに分かれてくれた。きれいでないと思う人もいるかもしれないが、わりと不安定な要素があった実験なので、これだけ分かれてくれれば充分にきれいな方である。心の中でガッツポーズ。
 これで、仮説を立てるための土台の一部ができたことになる。

MATLABで離散フーリエ変換

 博士の愛したかもしれない数式 - 周波数と駒で言及した
\displaystyle{X(k)=\log\left|\sum_{n=0}^{N-1}{w(n)x(n)\left(\cos\left(\frac{2\pi nk}{N}\right)-i\sin\left(\frac{2\pi nk}{N}\right)\right)}\right|}
という式をMATLABで計算したいとする。ここでnx(\cdot)w(\cdot)はそれぞれ離散時刻と入力信号と窓関数である。
 for文を使って定義をなぞるとこうなる(ただし窓関数は省略することにする)。

D = 8; %dimension
rng(0) %random seed
x = rand(D, 1); %input signal
X = zeros(D, 1);
for k = 0 : (D - 1)
    for n = 0 : (D - 1)
        phase = 2 * pi * n * k / D;
        X(k + 1) = X(k + 1) + ...
            (cos(phase) - i * sin(phase)) * x(n + 1);
    end
end
logX = log(abs(X));
%
logX' =
    1.4624   -0.1741    0.1288   -0.0093
   -0.4926   -0.0093    0.1288   -0.1741

 ところで、内側のfor文は内積なので、

D = 8; %dimension
rng(0) %random seed
x = rand(D, 1); %input signal
X = zeros(D, 1);
for k = 0 : (D - 1)
    phase = 2 * pi * (0 : (D - 1)) * k / D;
    X(k + 1) = (cos(phase) - i * sin(phase)) * x;
end
logX = log(abs(X));
%
logX' =
    1.4624   -0.1741    0.1288   -0.0093
   -0.4926   -0.0093    0.1288   -0.1741

と書ける。
 三角関数オイラーの公式で記述するとこうなる。

D = 8; %dimension
rng(0) %random seed
x = rand(D, 1); %input signal
X = zeros(D, 1);
for k = 0 : (D - 1)
    phase = 2 * pi * (0 : (D - 1)) * k / D;
    X(k + 1) = exp(-i * phase) * x;
end
logX = log(abs(X));
%
logX' =
    1.4624   -0.1741    0.1288   -0.0093
   -0.4926   -0.0093    0.1288   -0.1741

 さらに、外側のfor文も行列計算で省略できる。

D = 8; %dimension
rng(0) %random seed
x = rand(D, 1); %input signal
F = ((0 : (D - 1))') * 2 * pi * (0 : (D - 1)) / D;
X = exp(-i * F) * x;
logX = log(abs(X));
%
logX' =
    1.4624   -0.1741    0.1288   -0.0093
   -0.4926   -0.0093    0.1288   -0.1741

 離散フーリエ変換は意外とあっけなく書ける。
 MATLABに最初から付属しているFFTの関数と答えが一致していることを確認。

D = 8; %dimension
rng(0) %random seed
x = rand(D, 1); %input signal
X = fft(x);
logX = log(abs(X));
%
logX' =
    1.4624   -0.1741    0.1288   -0.0093
   -0.4926   -0.0093    0.1288   -0.1741

 これで本ブログのMATLABシリーズが一区切りついた。まだこれからもMATLABについては書くけど。

printf

 愛用しているMATLABであるが、この言語、printfという名前の関数がない。コマンドウィンドウに値などを出力したいときには、行の末尾にセミコロンをつけないのが最も簡単な方法となる。
 例えば、

a = 1;
%出力されない
a = 1
%以下出力
a =
     1

といった具合である。
 また、dispというコマンドもある。Rubyでいう"p"のような役割の関数である。

b = [2; 3];
disp(b)
%以下出力
     2
     3

 そして、printfはないがfprintfがCでいうprintfの役割になったりする。

fprintf("%03d\n", 4)
%以下出力
004

 このfprintfの使い方、わりと最近まで知らなかった。disp関数は強制的に改行されるが、fprintfは改行したくないときに便利である。