Circular Convolution using Matrix Method

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to compute circular
// convolution of two arrays
#include <iostream>
using namespace std;
  
#define MAX_SIZE 10
  
// Function to find circular convolution
void convolution(int* x, 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()
{
    int x[] = { 5, 7, 3, 2 };
    int n = sizeof(x) / sizeof(int);
    int h[] = { 1, 5 };
    int m = sizeof(h) / sizeof(int);
  
    convolution(x, h, n, m);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output:

15 32 38 17

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.