Main Content

cconv

n を法とする循環畳み込み

説明

c = cconv(a,b) は、ベクトル ab の畳み込みを行います。

c = cconv(a,b,n) では、ベクトル a および b が巡回的に畳み込まれます。ここで n は、結果として返されるベクトルの長さです。また、cconv を使用して 2 つのシーケンスの循環相互相関を計算できます。

すべて折りたたむ

異なる長さの 2 つの信号を生成します。それらの循環畳み込みと線形畳み込みを比較します。n の既定の値を使用します。

a = [1 2 -1 1];
b = [1 1 2 1 2 2 1 1];

c = cconv(a,b);            % Circular convolution
cref = conv(a,b);          % Linear convolution

dif = norm(c-cref)
dif = 9.7422e-16

結果のノルムは実質的にゼロで、これら 2 つの畳み込みがマシンの精度に与える結果はほぼ同じであると言えます。

2 つのベクトルを生成し、4 を法とする循環畳み込みを計算します。

a = [2 1 2 1];
b = [1 2 3 4];
c = cconv(a,b,4)
c = 1×4

    14    16    14    16

2 つの複素数シーケンスを生成します。cconv を使用して、それらの循環相互相関を比較します。相互相関の定義に適合するように 2 番目のオペランドを反転して共役させます。出力ベクトル長に 7 を指定します。

a = [1 2 2 1]+1i;
b = [1 3 4 1]-2*1i;
c = cconv(a,conj(fliplr(b)),7);

この結果を、xcorr を使用して計算した相互相関と比較します。

cref = xcorr(a,b);
dif = norm(c-cref)
dif = 3.3565e-15

5 サンプルの三角波と応答 H(z)=1-z-1 を持つ 1 次 FIR フィルターの 2 つの信号を生成します。

x1 = conv([1 1 1],[1 1 1])
x1 = 1×5

     1     2     3     2     1

x2 = [-1 1]
x2 = 1×2

    -1     1

既定の出力長でそれらの循環畳み込みを計算します。結果は、2 つの信号の線形畳み込みと等価になります。

ccnv = cconv(x1,x2)
ccnv = 1×6

   -1.0000   -1.0000   -1.0000    1.0000    1.0000    1.0000

lcnv = conv(x1,x2)
lcnv = 1×6

    -1    -1    -1     1     1     1

2 を法とする循環畳み込みは、線形畳み込みを 2 つの要素をもつ配列に分割してから配列を加算することと同等です。

ccn2 = cconv(x1,x2,2)
ccn2 = 1×2

    -1     1

nl = numel(lcnv);
mod2 = sum(reshape(lcnv,2,nl/2)')
mod2 = 1×2

    -1     1

3 を法とする循環畳み込みを計算し、エイリアシングした線形畳み込みと比較します。

ccn3 = cconv(x1,x2,3)
ccn3 = 1×3

     0     0     0

mod3 = sum(reshape(lcnv,3,nl/3)')
mod3 = 1×3

     0     0     0

出力長が畳み込み長より小さく、畳み込み長が出力長で割り切れない場合は、加算する前に畳み込みをゼロでパディングします。

c = 5;
z = zeros(c*ceil(nl/c),1);
z(1:nl) = lcnv;

ccnc = cconv(x1,x2,c)
ccnc = 1×5

    0.0000   -1.0000   -1.0000    1.0000    1.0000

modc = sum(reshape(z,c,numel(z)/c)')
modc = 1×5

     0    -1    -1     1     1

出力長が畳み込み長と等しいか、またはそれより大きい場合は、畳み込みをパディングし、加算は行いません。

d = 13;
z = zeros(d*ceil(nl/d),1);
z(1:nl) = lcnv;

ccnd = cconv(x1,x2,d)
ccnd = 1×13

   -1.0000   -1.0000   -1.0000    1.0000    1.0000    1.0000    0.0000   -0.0000    0.0000    0.0000    0.0000   -0.0000   -0.0000

modd = z'
modd = 1×13

    -1    -1    -1     1     1     1     0     0     0     0     0     0     0

次の例では、Parallel Computing Toolbox™ ソフトウェアが必要です。どの GPU がサポートされているかについては、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。

加法性ホワイト ガウス ノイズの 1 kHz の正弦波から構成される 2 つの信号を作成します。サンプル レートは 10 kHz です。

Fs = 1e4;
t = 0:1/Fs:10-(1/Fs);
x = cos(2*pi*1e3*t)+randn(size(t));
y = sin(2*pi*1e3*t)+randn(size(t));

gpuArray を使用して xy を GPU に入力します。GPU を使用して循環畳み込みを取得します。

x = gpuArray(x);
y = gpuArray(y);
cirC = cconv(x,y,length(x)+length(y)-1);

結果を x と y の線形畳み込みと比較します。

linC = conv(x,y);
norm(linC-cirC,2)
ans =

   1.4047e-08

gather を使用して、循環畳み込み cirC を MATLAB® ワークスペースに返します。

cirC = gather(cirC);

入力引数

すべて折りたたむ

入力配列。ベクトルとして指定します。

例: sin(2*pi*(0:9)/10) + randn([1 10])/10 では、行ベクトルとしてノイズを含んだ正弦波を指定します。

データ型: single | double
複素数のサポート: あり

畳み込みの長さ。正の整数として指定します。n を指定しない場合、畳み込みの長さは length(a)+length(b)-1 です。

出力引数

すべて折りたたむ

入力ベクトルの循環畳み込み。ベクトルとして返されます。

ヒント

長いシーケンスでは、循環畳み込みの方が線形畳み込みよりも速くなる場合があります。

参照

[1] Orfanidis, Sophocles J. Introduction to Signal Processing. Englewood Cliffs, NJ: Prentice-Hall, 1996, pp. 524–529.

拡張機能

C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。

バージョン履歴

R2007a で導入