Circular Convolution using Matrix Method - GeeksforGeeks

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 8Input: 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++
Java
Python3
C#
Javascript
// C++ program to compute circular// convolution of two arrays#include <bits/stdc++.h>using namespace std; #define MAX_SIZE 10 // Function to find circular convolutionvoid 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 programint 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 arraysclass 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 arraysMAX_SIZE = 10; # Function to find circular convolutiondef 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 programif __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 arraysusing 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>
  
15 32 38 17
 
Time Complexity: O(MAX_SIZE * MAX_SIZE)Auxiliary Space: O(MAX_SIZE * MAX_SIZE) 
ankthon
princiraj1992
29AjayKumar
deepesh08
suresh07
pankajsharmagfg
ashutoshsinghgeeksforgeeks
Technical Scripter 2019
Algorithms
Greedy
Technical Scripter
Greedy
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
DSA Sheet by Love Babbar
How to Start Learning DSA?
Difference between Algorithm, Pseudocode and Program
K means Clustering - Introduction
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Dijkstra's shortest path algorithm | Greedy Algo-7
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Program for array rotation
Write a program to print all permutations of a given string