らくがきちょう

文字数制限の無いTwitter的な

高校数学の謎問題と、それを応用した信号処理(ゼロクロスの判定、立ち上がり・立ち消えの検出)

高校の数学で時折見かける練習問題の中で個人的に思い出深いものの中に、こういうのがある。

2次方程式x2 + 2x - 4 = 0の解xが、1<x<2の範囲にあることを示せ

模範解答?はこんな感じだ*1

f(x) = x2 + 2x - 4 = 0 とおくと、f(1) = -1, f(2) = 4なので、1<x<2の範囲のあるxに対してf(x) = 0となる値が存在する。

高校生として説明を受けたときの自分の感覚は覚えていない。でも、高校の数学教師とか塾バイトとかやってたころに生徒から質問を受けたことがあり、こう返された。「書いてあることはわかる。でも意味分からん。解いたら済むやん!!」

全くその通りだ。解の公式を使えば一瞬で解けるのに、解かずに存在範囲だけ曖昧に特定して何になるのか。謎問題である。

実はこの問題は数学III微積分で習うであろう中間値の定理に対する伏線になっているといえばなっている。そのことに初めて気づいたのは恥ずかしながら高校教師2年目か3年目のことだったと思う。

何かの拍子に気づいて、そういうことか~~~~ってなった。

とはいえ中間値の定理の話をするわけにもいかないので、以後、「もっとえげつない方程式でよう解かんような場合でも、解はこの辺なんやで、って同じやり口で示すことが出来るわけですね」ぐらいでお茶を濁すことにした。

 

この問題が思い出深い理由の1つは上のような思い出である。

2つめそして本編は、高校教師をやめて大学院に行ってからのこと。信号処理のプログラミング実習中に、上記の模範解答を唐突に思い出したのだ。

この模範解答のやり口は信号のゼロクロスや立ち上がり・立ち消えの検出に応用できるのである。

 

ゼロクロスの検出

これはまったくそのまんまである。ゼロクロスするxこそ解なので。

Matlabだと、xというデータ(1列のベクトル)があったとすれば、次のようなコードでゼロクロスの場所を簡単に検出できる。

crs = x(1:end-1) .* x(2:end);

zc = find(crs < 0);

 crsはx(1)*x(2), x(2)*x(3), x(3)*x(4), ... という隣り合う値同士を掛け算した系列である。そしてzcは、「crsが負になってる場所(インデックス)を探せ」ということ。

図示すると、こういうこと。

f:id:MshrOkn:20201022165640p:plain

ゼロクロスする前と後では符号が変わるので、その瞬間だけcrsの符号が-になり、そこ以外ではcrsの符号は+になる。したがって、crsが負になるインデックスを見つければそこがゼロクロスの瞬間というわけである。

 

ゼロクロスの検出は、たとえば音声認識などで子音と母音をざっくり分けるのに利用できたりする。*2

下図は「ざ~じ~ず~ぜ~ぞ~」と言ってみた音声の録音波形からノイズをカットした上で、ゼロクロスを検出してみたものである(赤いドットがゼロクロスしている場所)。

赤いドットがしゃべっている場所=振幅の大きい場所のうち、各回の前半に偏っているのが分かるだろうか。

「z」のような摩擦音は母音と比べると雑音に近い非周期的な波形をしているので、子音が鳴っている時間帯は母音が鳴っている時間帯と比べて圧倒的にゼロクロスが多くなる。

見ての通り「じ」なんかは子音が長く鳴りがちであまりうまく分けられていないので、実用にはさらに工夫がいりそうだけど、ともかくゼロクロスの検出だけでもこのぐらいは分けることができる。

f:id:MshrOkn:20201022170006p:plain

 

立ち上がり・立ち消えの検出

たとえば歩行やランニングの計測ではフットスイッチを装着するとか床反力計の上を歩いてもらうとかをする。そうしたデータの分析では、足が地面に付いている時間帯と付いていない時間帯を分けたくなることが多々ある。

数歩程度なら手作業でやっても良いのだが、何十歩もあるとか、1人数歩でも何十人とデータを取ったとかの場合、手作業ではとてもやっていられない。

こんなときも、上と同じ仕組みで足の接地・離地の瞬間を自動検出できる。

xをフットスイッチまたは床反力計のデータとすると、このようなコードだ。

thr = 0.2;

crs = (x(1:end-1) - thr) .* (x(2:end) - thr);

zc = find(crs < 0);

図示すると、次のようになる。 

f:id:MshrOkn:20201022172759p:plain

つまり立ち上がりも立ち消えもx-thrの符号の変わり目なので、隣り合う値同士の積crsが負の値になる場所を探せばいいのである。

筋電図や音声などの信号の立ち上がり・立ち消えも、全波整流して包絡線を求めて…という前処理こそ必要だが、S/N比が良ければ同じ方法で検出できる。

 

 

実習の担当の先生は謎問題との関係なんて一言も触れなかったんだけど、コードの説明を受けたときに電撃が走ったのを覚えてる。「これ進研ゼミで見たやつだ!」的な。

久しぶりに高校数学の練習問題や教科書傍用問題集や大学入試問題集なんか見てみたら、他にもこういうの見つかったりするんだろうか。

なんてことを思いながら幾星霜。特に改めて見てみたりはしてないのだけど。

似たような経験があったらぜひ教えてください。

*1:連続性を示さないと…とか細かいことはおいといて

*2:子音と母音を分けて何がうれしいか。たとえばだけど、これは「おっさんでも美少女の声が出せる」というボイスチェンジャー的な物を作るための第一歩だったりする。実はおっさんの声でも美少女の声でも子音部分の音はほとんど変わらない。違うのは母音の高さと音色である。なので、母音の部分だけ取り出して音を高くして音色を調節するということができれば、おっさんの声が美少女の声になるのだ。理論上。