LoginSignup
13
3

More than 3 years have passed since last update.

【MATLAB】畳み込み積分について学んでみた

Last updated at Posted at 2019-10-04

あらすじ

制御工学の学習中に頻繁に出てくる、畳み込み積分。
matlabにも、関数「conv」として用意されている。

折角matlabが使用できる環境にあるので、matlabを
使用して畳み込み積分について学んでみる。

この記事でやること

  1. 畳み込み積分の基本及びその用途について記載
  2. 手計算で畳み込み積分を計算
  3. matlabを使用して畳み込み積分を計算
  4. ②と③の結果の突き合わせ

1-1. 畳み込み積分の基本 - 畳み込み積分って何?

合成積とも呼ばれる畳み込み積分は、関数 $f(x)$ と $g(x)$ が存在する時、以下式にて定義する。

         $h(x) = \int_{-∞}^{∞} f(τ)g(x-τ)dτ = \int_{-∞}^{∞} f(x-τ)g(τ)dτ$

離散系で考える場合は畳み込み和と言い、以下式にて定義される。

h(m) = \sum f(n)g(m-n) = \sum f(m-n)g(n)

1-2. 畳み込み積分の用途 - 何のために使うの?

システムにデルタ関数を入力した場合のインパルス応答が分かる、という利点がある。
入力信号を $f(x)$、デルタ関数を $g(x)$ と定義すれば、畳み込み積分の結果 $h(x)$ がシステムの出力として表される。
離散系で考えれば、どんな信号もサンプリングタイムを幅とするインパルス(状)の信号の連続であるため、
畳み込み積分によってインパルス応答が分かるということは、あらゆる入力信号に対する出力信号が
「畳み込み」で分かる、ということになる。

2. 手計算で畳み込み積分を計算

$f(x)=sin(x)、g(x)=cos(x)$ として、
以下の畳み込み積分 を計算する。

h(τ) = \int_{0}^{3} sin(τ)cos(2-τ)dτ

[ 回答 ]

積和公式
$sin(α)cos(β) = \dfrac{1}{2} \{sin(α+β)+sin(α-β)\}$
を使用し、

\begin{align}
h(τ)&=\dfrac{1}{2}\int_{0}^{3} \{sin(2)-sin(2τ-2)\}dτ\\
\end{align}

とする。

$sin(2)$は定数なので$τ$で積分すれば単純に$τ$がつくだけ。
$sin(2τ-2)$ は $t=2τ-2$ として合成関数の積分公式
$\int t^{-1}dx = \dfrac{1}{n+1}・t^{n+1}・\dfrac{1}{t^{\prime}}+C$
を使用して
$\int sin(2τ-2)dτ={(cos(2τ-2))・\dfrac{1}{2}}$
とすると

\begin{align}
h(τ)&=\dfrac{1}{2}\left[τsin(2)-\dfrac{1}{2}\{cos(2τ-2)\}\right]^3_0\\
&=\dfrac{1}{2}\{3sin(2)-0sin(2)-\dfrac{1}{2}((cos(4)-cos(-2))\}\\
&=1.4233\\
\end{align}

3. matlabを使用して畳み込み積分を計算

% 条件
range = [0 3]; % 定積分の範囲
ts = 0.1; % サンプリングタイム
x = range(1):ts:range(2);

% ① 連続時間系
h = @(x) sin(x) .* cos(2 - x);
cans = integral(h, range(1), range(2)); % 連続時間系積分の解

% ② 離散時間系
f = sin(x);
g = cos(2 - x);
h = f .* g;
dans = sum(h) * ts; % 離散時間系積分の解

% 連続時間系と離散時間系の解の差分
err = abs(cans - dans);

答え(cans)は1.4233で、手計算での結果と一致した。
※ 離散時間系はついでで記述

ところで関数「conv」は?

結局、関数「conv」を使用せずに計算した。

関数convについて公式の説明を見てみたが、「畳み込みおよび多項式乗算」と
タイトルにあるように、厳密には畳み込み「積分」まではやってくれないらしい。
式:$\int_{-∞}^{∞} f(τ)g(x-τ)dτ$ のうち、$ f(τ) $ と $ g(x-τ)$ の乗算のみをやってくれる関数のようだ。

しかも無名関数として$sin(x)$などを宣言しても引数として使えず、スカラやベクトル(一次元配列)を
引数として使うしかない。

同じ長さの2つの配列の要素同士を演算をするためのものでもないため、
結局convを畳み込み積分に使用する方法が分からなかった。
(オマエが知らないだけで普通に使えるわ!という声が聞こえてきそうだ)

もしかするとSymbolic math toolboxがあればうまく活用できたのかもしれないが、
持ってないため試すことができなかった。残念。。

参考にさせていただいた情報

大変お世話になりました。誠にありがとうございます。

[ネット]

内容 リンク先
畳み込み積分の用途 http://zellij.hatenablog.com/entry/20110924/p1
同上 https://www.noe.co.jp/technology/18/18inv1.html
置換積分 https://yorikuwa.com/m3402/

最後に

ここはこうしたほうがいいぞ!ここ間違っているぞ!等もしございましたら、
お手数ですがご指摘いただけますとそれはもう大変喜びます。

13
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
3