Given two array X[] and H[] of length N and M respectively, the task is to find the circular convolution of the given arrays using Matrix method. Multiplication of the Circularly Shifted Matrix and the column-vector is the Circular-Convolution of the arrays.
Examples:
Input: X[] = {1, 2, 4, 2}, H[] = {1, 1, 1}
Output: 7 5 7 8
Input: X[] = {5, 7, 3, 2}, H[] = {1, 5}
Output: 15 32 38 17
Explanation:
- Create a circularly shifted Matrix circular_shift_mat of K * K using the elements of array whose length is maximum(Xn in this case) where K is MAX(N, M).

- Create a column-vector col_vec of length K
- Insert the elements of the array Hm into the col_vec in positions [0, m).
- As K = max(N, M), here N; M < K. Therefore fill the rest of the positions of col_vec [m, K) with 0.Therefore the col_vec will be
col_vec = { 1, 1, 1, 0 }- Multiply the circular_shift_mat and the col_vec
- Multiplication of the Circularly Shifted Matrix (circular_shift_mat) and the column-vector (col_vec) is the Circular-Convolution of the arrays.
Approach:
- Create a Circularly shifted Matrix of N * N using the elements of array of the maximum length.
- Create a column-vector of length N using elements of another array and fill up rest of the positions by 0.
- Multiplication of Matrix and the column-vector is the Circular-Convolution of arrays.
Below is the implementation of the above approach.
// C++ program to compute circular
// convolution of two arrays
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 10
// Function to find circular convolution
void convolution(vector<int>& x, vector<int>& h, int n, int m)
{
int row_vec[MAX_SIZE], col_vec[MAX_SIZE];
int out[MAX_SIZE] = { 0 };
int circular_shift_mat[MAX_SIZE][MAX_SIZE];
// Finding the maximum size between the
// two input sequence sizes
int maxSize = n > m ? n : m;
// Copying elements of x to row_vec and padding
// zeros if size of x < maxSize
for (int i = 0; i < maxSize; i++) {
if (i >= n) {
row_vec[i] = 0;
}
else {
row_vec[i] = x[i];
}
}
// Copying elements of h to col_vec and padding
// zeros if size of h is less than maxSize
for (int i = 0; i < maxSize; i++) {
if (i >= m) {
col_vec[i] = 0;
}
else {
col_vec[i] = h[i];
}
}
// Generating 2D matrix of
// circularly shifted elements
int k = 0, d = 0;
for (int i = 0; i < maxSize; i++) {
int curIndex = k - d;
for (int j = 0; j < maxSize; j++) {
circular_shift_mat[j][i] = row_vec
[curIndex % maxSize];
curIndex++;
}
k = maxSize;
d++;
}
// Computing result by matrix
// multiplication and printing results
for (int i = 0; i < maxSize; i++) {
for (int j = 0; j < maxSize; j++) {
out[i] += circular_shift_mat[i][j]
* col_vec[j];
}
cout << out[i] << " ";
}
}
// Driver program
int main()
{
vector<int> x = { 5, 7, 3, 2 };
int n = x.size();
vector<int> h = { 1, 5 };
int m = h.size();
convolution(x, h, n, m);
return 0;
}
// Java program to compute circular
// convolution of two arrays
class GFG
{
final static int MAX_SIZE = 10 ;
// Function to find circular convolution
static void convolution(int []x, int []h, int n, int m)
{
int row_vec[] = new int[MAX_SIZE];
int col_vec[] = new int[MAX_SIZE];
int out[] = new int [MAX_SIZE];
int circular_shift_mat[][] = new int[MAX_SIZE][MAX_SIZE];
// Finding the maximum size between the
// two input sequence sizes
int maxSize = n > m ? n : m;
// Copying elements of x to row_vec and padding
// zeros if size of x < maxSize
for (int i = 0; i < maxSize; i++)
{
if (i >= n)
{
row_vec[i] = 0;
}
else
{
row_vec[i] = x[i];
}
}
// Copying elements of h to col_vec and padding
// zeros if size of h is less than maxSize
for (int i = 0; i < maxSize; i++)
{
if (i >= m)
{
col_vec[i] = 0;
}
else
{
col_vec[i] = h[i];
}
}
// Generating 2D matrix of
// circularly shifted elements
int k = 0, d = 0;
for (int i = 0; i < maxSize; i++)
{
int curIndex = k - d;
for (int j = 0; j < maxSize; j++)
{
circular_shift_mat[j][i] =
row_vec[curIndex % maxSize];
curIndex++;
}
k = maxSize;
d++;
}
// Computing result by matrix
// multiplication and printing results
for (int i = 0; i < maxSize; i++)
{
for (int j = 0; j < maxSize; j++)
{
out[i] += circular_shift_mat[i][j] * col_vec[j];
}
System.out.print(out[i] + " ");
}
}
// Driver program
public static void main (String[] args)
{
int x[] = { 5, 7, 3, 2 };
int n = x.length;
int h[] = { 1, 5 };
int m = h.length;
convolution(x, h, n, m);
}
}
// This code is contributed by AnkitRai01
# Python program to compute circular
# convolution of two arrays
MAX_SIZE = 10;
# Function to find circular convolution
def convolution(x, h, n, m):
row_vec = [0] * MAX_SIZE;
col_vec = [0] * MAX_SIZE;
out = [0] * MAX_SIZE;
circular_shift_mat = [[0 for i in range(MAX_SIZE)]
for j in range(MAX_SIZE)] ;
# Finding the maximum size between the
# two input sequence sizes
if(n > m ):
maxSize = n;
else:
maxSize = m;
# Copying elements of x to row_vec and padding
# zeros if size of x < maxSize
for i in range(maxSize):
if (i >= n):
row_vec[i] = 0;
else:
row_vec[i] = x[i];
# Copying elements of h to col_vec and padding
# zeros if size of h is less than maxSize
for i in range(maxSize):
if (i >= m):
col_vec[i] = 0;
else:
col_vec[i] = h[i];
# Generating 2D matrix of
# circularly shifted elements
k = 0;
d = 0;
for i in range(maxSize):
curIndex = k - d;
for j in range(maxSize):
circular_shift_mat[j][i] = \
row_vec[curIndex % maxSize];
curIndex += 1;
k = maxSize;
d += 1;
# Computing result by matrix
# multiplication and printing results
for i in range(maxSize):
for j in range(maxSize):
out[i] += circular_shift_mat[i][j] * \
col_vec[j];
print(out[i], end = " ");
# Driver program
if __name__ == '__main__':
x = [ 5, 7, 3, 2 ];
n = len(x);
h = [ 1, 5 ];
m = len(h);
convolution(x, h, n, m);
# This code is contributed by 29AjayKumar
// C# program to compute circular
// convolution of two arrays
using System;
class GFG
{
readonly static int MAX_SIZE = 10 ;
// Function to find circular convolution
static void convolution(int []x, int []h,
int n, int m)
{
int []row_vec = new int[MAX_SIZE];
int []col_vec = new int[MAX_SIZE];
int []out_ = new int [MAX_SIZE];
int [,]circular_shift_mat =
new int[MAX_SIZE,MAX_SIZE];
// Finding the maximum size between the
// two input sequence sizes
int maxSize = n > m ? n : m;
// Copying elements of x to row_vec and padding
// zeros if size of x < maxSize
for (int i = 0; i < maxSize; i++)
{
if (i >= n)
{
row_vec[i] = 0;
}
else
{
row_vec[i] = x[i];
}
}
// Copying elements of h to col_vec and padding
// zeros if size of h is less than maxSize
for (int i = 0; i < maxSize; i++)
{
if (i >= m)
{
col_vec[i] = 0;
}
else
{
col_vec[i] = h[i];
}
}
// Generating 2D matrix of
// circularly shifted elements
int k = 0, d = 0;
for (int i = 0; i < maxSize; i++)
{
int curIndex = k - d;
for (int j = 0; j < maxSize; j++)
{
circular_shift_mat[j, i] =
row_vec[curIndex % maxSize];
curIndex++;
}
k = maxSize;
d++;
}
// Computing result by matrix
// multiplication and printing results
for (int i = 0; i < maxSize; i++)
{
for (int j = 0; j < maxSize; j++)
{
out_[i] += circular_shift_mat[i, j] *
col_vec[j];
}
Console.Write(out_[i] + " ");
}
}
// Driver program
public static void Main(String[] args)
{
int []x = {5, 7, 3, 2};
int n = x.Length;
int []h = {1, 5};
int m = h.Length;
convolution(x, h, n, m);
}
}
// This code is contributed by PrinciRaj1992
<script>
// JavaScript program to compute circular
// convolution of two arrays
let MAX_SIZE = 10 ;
// Function to find circular convolution
function convolution(x, h, n, m)
{
let row_vec = new Array(MAX_SIZE);
row_vec.fill(0);
let col_vec = new Array(MAX_SIZE);
col_vec.fill(0);
let out = new Array(MAX_SIZE);
out.fill(0);
let circular_shift_mat = new Array(MAX_SIZE);
circular_shift_mat.fill(0);
for (let i = 0; i < MAX_SIZE; i++)
{
circular_shift_mat[i] = new Array(MAX_SIZE);
for (let j = 0; j < MAX_SIZE; j++)
{
circular_shift_mat[i][j] = 0;
}
}
// Finding the maximum size between the
// two input sequence sizes
let maxSize = n > m ? n : m;
// Copying elements of x to row_vec and padding
// zeros if size of x < maxSize
for (let i = 0; i < maxSize; i++)
{
if (i >= n)
{
row_vec[i] = 0;
}
else
{
row_vec[i] = x[i];
}
}
// Copying elements of h to col_vec and padding
// zeros if size of h is less than maxSize
for (let i = 0; i < maxSize; i++)
{
if (i >= m)
{
col_vec[i] = 0;
}
else
{
col_vec[i] = h[i];
}
}
// Generating 2D matrix of
// circularly shifted elements
let k = 0, d = 0;
for (let i = 0; i < maxSize; i++)
{
let curIndex = k - d;
for (let j = 0; j < maxSize; j++)
{
circular_shift_mat[j][i] =
row_vec[curIndex % maxSize];
curIndex++;
}
k = maxSize;
d++;
}
// Computing result by matrix
// multiplication and printing results
for (let i = 0; i < maxSize; i++)
{
for (let j = 0; j < maxSize; j++)
{
out[i] += circular_shift_mat[i][j] * col_vec[j];
}
document.write(out[i] + " ");
}
}
let x = [ 5, 7, 3, 2 ];
let n = x.length;
let h = [ 1, 5 ];
let m = h.length;
convolution(x, h, n, m);
</script>
Output:
15 32 38 17
Time Complexity: O(MAX_SIZE * MAX_SIZE)
Auxiliary Space: O(MAX_SIZE * MAX_SIZE)