ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

cconv

N を法とする循環たたみ込み

構文

c = cconv(a,b,n)
c = cconv(gpuArrayA,gpuArrayB,n)

説明

循環たたみ込みは、2 つの離散フーリエ変換 (DFT) シーケンスのたたみ込みに使用します。長いシーケンスでは、循環たたみ込みの方が線形たたみ込みよりも速くなる場合があります。

c = cconv(a,b,n) では、ベクトル a および b が巡回的にたたみ込まれます。ここで n は、結果として返されるベクトルの長さです。n を指定しないと、既定値の length(a)+length(b)-1 が使用されます。n = length(a)+length(b)-1 の場合、循環たたみ込みは、conv を使用して計算した線形たたみ込みと等価になります。また、cconv を使用して 2 つのシーケンスの循環相互相関を計算できます。

c = cconv(gpuArrayA,gpuArrayB,n) は、gpuArray クラスの入力ベクトルの循環たたみ込みを返します。gpuArray オブジェクトの詳細については、「GPU での配列の確立」を参照してください。cconvgpuArray と共に使用するには、Parallel Computing Toolbox™ ソフトウェアおよび CUDA 対応の NVIDIA GPU (Compute Capability 1.3 以上) が必要です。詳細は、http://www.mathworks.com/products/parallel-computing/requirements.html を参照してください。出力ベクトル c は、gpuArray オブジェクトです。GPU を使用して循環たたみ込みを計算する例については、GPU を使用した循環たたみ込みを参照してください。

すべて折りたたむ

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

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

    14    16    14    16

異なる長さの 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 つの複素数シーケンスを生成します。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])
x2 = [-1 1]
x1 =

     1     2     3     2     1


x2 =

    -1     1

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

ccnv = cconv(x1,x2)

lcnv = conv(x1,x2)
ccnv =

   -1.0000   -1.0000   -1.0000    1.0000    1.0000    1.0000


lcnv =

    -1    -1    -1     1     1     1

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

ccn2 = cconv(x1,x2,2)

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

    -1     1


mod2 =

    -1     1

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

ccn3 = cconv(x1,x2,3)

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

     0     0     0


mod3 =

     0     0     0

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

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

ccnc = cconv(x1,x2,c)

modc = sum(reshape(z,c,numel(z)/c)')
ccnc =

    0.0000   -1.0000   -1.0000    1.0000    1.0000


modc =

     0    -1    -1     1     1

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

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

ccnd = cconv(x1,x2,d)

modd = z'
ccnd =

  Columns 1 through 7

   -1.0000   -1.0000   -1.0000    1.0000    1.0000    1.0000    0.0000

  Columns 8 through 13

   -0.0000    0.0000    0.0000    0.0000   -0.0000   -0.0000


modd =

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

以下の例では、Parallel Computing Toolbox ソフトウェアおよび CUDA 対応 NVIDIA GPU (Compute Capability 1.3 以上) が必要です。詳細は、http://www.mathworks.com/products/parallel-computing/requirements.html を参照してください。

加法性ホワイト ガウス ノイズの 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);

結果を xy の線形たたみ込みと比較します。

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

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

cirC = gather(cirC);

参考文献

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

参考

|

R2007a で導入

この情報は役に立ちましたか?