设有arrA和arrB两个一维数组,分别如下:
arrA = 1 2 3 4
arrB = 2 3 1
根据卷积定义,arrA*arrB的卷积结果为2 7 13 19 15 4,具体过程为:
① arrA的所有元素和arrB的第0个元素相乘,结果为
2 4 6 8
② arrA的所有元素和arrB的第1个元素相乘,结果为
3 6 9 12
③ arrA的所有元素和arrB的第2个元素相乘,结果为
1 2 3 4
④ 以上三步的结果,按照如下方法累加
2 4 6 8
3 6 9 12
1 2 3 4
+
2 7 13 19 15 4
也就是说,每次arrA中所有元素和arrB中第j个元素相乘后,得到的临时卷积结果,与上一次临时卷积结果均要做叠加,但是叠加不是对应位置的元素叠加,而是第j次叠加时,需要将第j次临时卷积结果在第j-1次的基础上,再往右偏移1个位置。具体Java代码如下:
// 计算方法和计算过程演示见如下网址:
// https://www.zhihu.com/question/22298352/answer/34267457
public class ConvolutionOf1D {
public static void main(String[] args) {
// arrA和arrB是两个进行卷积的一维数组
int[] arrA = { 1, 2, 3, 4 };
int[] arrB = { 2, 3, 1 };
// bias是每次更新卷积结果,计算时的偏移量
int bias = 0;
// arrC存放卷积结果
int[] arrC = new int[arrA.length + arrB.length - 1];
// tmpAB存放第i次临时卷积结果
int[] tmpAB = new int[arrA.length];
// 计算卷积过程
for (int j = 0; j < arrB.length; j++) {
// 计算arrA中所有元素和arrB中第j个元素的临时卷积,结果存放在tmpAB中
for (int i = 0; i < arrA.length; i++) {
tmpAB[i] = arrA[i] * arrB[j];
}
// 更新卷积结果
for (int p = 0, q = 0; p < arrC.length && q < tmpAB.length; p++, q++) {
arrC[p + bias] = arrC[p + bias] + tmpAB[q];
}
bias++;
}
for (int k : arrC) {
System.out.print(k + " ");
}
}
}