给定两个分别为长度N和M的数组X []和H [] ,任务是使用矩阵方法找到给定数组的圆卷积。循环移位矩阵与列向量的乘积是数组的循环卷积。
例子:
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
解释:
- 使用长度最大(在此情况下为X n )的数组元素(其中K为MAX(N,M))创建K * K的循环移位矩阵circle_shift_mat 。
- 创建一个长度为K的列向量col_vec
- 将数组H m的元素插入到col_vec中的[0,m)位置。
- 由于K = max(N,M),这里N; M
- 因此,col_vec将是
col_vec = { 1, 1, 1, 0 }
- 乘以circular_shift_mat和col_vec
- 循环移位矩阵(circular_shift_mat)与列向量(col_vec)的乘积是数组的循环卷积。
- 因此,col_vec将是
方法:
- 使用最大长度的数组元素创建N * N的循环移位矩阵。
- 使用另一个数组的元素创建一个长度为N的列向量,并用0填充其余位置。
- 矩阵与列向量的乘积是数组的循环卷积。
下面是上述方法的实现。
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(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;
}
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
输出:
15 32 38 17