# Circular Convolution using Matrix Method

• Last Updated : 26 Nov, 2021

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).

Circularly shifted matrix of the array Xn.

• 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++

 `// C++ program to compute circular` `// convolution of two arrays` `#include ` `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

 `// 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`

## Python3

 `# 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#

 `// 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`

## Javascript

 ``

Output:

`15 32 38 17`

Time Complexity: O(MAX_SIZE * MAX_SIZE)
Auxiliary Space: O(MAX_SIZE * MAX_SIZE)

My Personal Notes arrow_drop_up
Related Articles