Modulo-n circular convolution
Generate two signals of different lengths. Compare their circular convolution and their linear convolution. Use the default value for 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
The resulting norm is virtually zero, which shows that the two convolutions produce the same result to machine precision.
Generate two vectors and compute their modulo-4 circular convolution.
a = [2 1 2 1]; b = [1 2 3 4]; c = cconv(a,b,4)
c = 1×4
14 16 14 16
Generate two complex sequences. Use cconv
to compute their circular cross-correlation. Flip and conjugate the second operand to comply with the definition of cross-correlation. Specify an output vector length of 7.
a = [1 2 2 1]+1i; b = [1 3 4 1]-2*1i; c = cconv(a,conj(fliplr(b)),7);
Compare the result to the cross-correlation computed using xcorr
.
cref = xcorr(a,b); dif = norm(c-cref)
dif = 3.3565e-15
Generate two signals: a five-sample triangular waveform and a first-order FIR filter with response .
x1 = conv([1 1 1],[1 1 1])
x1 = 1×5
1 2 3 2 1
x2 = [-1 1]
x2 = 1×2
-1 1
Compute their circular convolution with the default output length. The result is equivalent to the linear convolution of the two signals.
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
The modulo-2 circular convolution is equivalent to splitting the linear convolution into two-element arrays and summing the arrays.
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
Compute the modulo-3 circular convolution and compare it to the aliased linear convolution.
ccn3 = cconv(x1,x2,3)
ccn3 = 1×3
0 0 0
mod3 = sum(reshape(lcnv,3,nl/3)')
mod3 = 1×3
0 0 0
If the output length is smaller than the convolution length and does not divide it exactly, pad the convolution with zeros before adding.
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
If the output length is equal to or larger than the convolution length, pad the convolution and do not add.
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
The following example requires Parallel Computing Toolbox™ software. Refer to GPU Support by Release (Parallel Computing Toolbox) to see what GPUs are supported.
Create two signals consisting of a 1 kHz sine wave in additive white Gaussian noise. The sample rate is 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));
Put x
and y
on the GPU using gpuArray
. Obtain the circular convolution using the GPU.
x = gpuArray(x); y = gpuArray(y); cirC = cconv(x,y,length(x)+length(y)-1);
Compare the result to the linear convolution of x and y.
linC = conv(x,y); norm(linC-cirC,2)
ans = 1.4047e-08
Return the circular convolution, cirC
, to the MATLAB® workspace using gather
.
cirC = gather(cirC);
a
, b
— Input arraysgpuArray
objectInput array, specified as vectors or gpuArray
objects. See
Run MATLAB Functions on a GPU (Parallel Computing Toolbox) for details
on gpuArray
objects. Using cconv
with
gpuArray
objects requires Parallel Computing Toolbox™ software. Refer to GPU Support by Release (Parallel Computing Toolbox) to see what GPUs
are supported.
Example: sin(2*pi*(0:9)/10) + randn([1 10])/10
specifies a noisy
sinusoid as a row vector.
Example: gpuArray(sin(2*pi*(0:9)/10) + randn([1 10])/10)
specifies
a noisy sinusoid as a
object.gpuArray
Data Types: single
| double
Complex Number Support: Yes
n
— Convolution lengthConvolution length, specified as a positive integer. If you do not specify
n
, then the convolution has length
length(a)+length(b)-1
.
c
— Circular convolutiongpuArray
objectCircular convolution of input vectors, returned as a vector or
gpuArray
.
For long sequences, circular convolution can be faster than linear convolution.
[1] Orfanidis, Sophocles J. Introduction to Signal Processing. Englewood Cliffs, NJ: Prentice-Hall, 1996, pp. 524–529.
This function fully supports GPU arrays. For more information, see Run MATLAB Functions on a GPU (Parallel Computing Toolbox).
You have a modified version of this example. Do you want to open this example with your edits?