通过乘以内存中的数字列表进行卷积,所以是逆卷积算法?
Convolution by multiplying list of numbers in memory, so an inverse convolution algorithm?
虽然 "convolutions are multiplications in the frequency domain",但从字面上看,它们似乎也是乘法。例如,如果我将内存中的数字相邻地连接成一种列表:
5: (byte) 00000101
22: (byte) 00010110
7: (byte) 00000111
8: (byte) 00001000
Becomes:
(Int32) 00000101000101100000011100001000
然后将这个结果 list/number 乘以另一个这样的列表,结果是一个列表与另一个列表的卷积。以下 C# 程序对此进行了演示:
using System;
public class Program
{
public static void Main(string[] args)
{
var A = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
var a = combine_to_Int64(A);
var B = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
var b = combine_to_Int64(B);
var c = a * b;
var C = separate_to_8_byte(c);
var d = deconvolution(c, b); // not correct
var D = separate_to_8_byte(d);
Console.WriteLine(
"The convolution of (" + to_string(A) + ") with ("
+ to_string(B) + ") is: (" + to_string(C) + ")");
Console.WriteLine(
"The deconvolution of (" + to_string(C) + ") with ("
+ to_string(B) + ") is: (" + to_string(D) + ")");
}
public static Int64 convolution(Int64 a, Int64 b)
{
return a * b;
}
private static Int64 combine_to_Int64(byte[] n)
{
if (n.Length == 4)
return n[0] + 65536 * n[1] + 4294967296 * n[2] +
281474976710656 * n[3];
else if (n.Length == 8)
return n[0] + 256 * n[1] + 65536 * n[2] + 16777216 * n[3] +
4294967296 * n[4] + 1099511627776 * n[5] +
281474976710656 * n[6] + 72057594037927936 * n[7];
else
throw new ArgumentException();
}
private static Int16[] separate_to_4_Int16(Int64 a)
{
return new []{(Int16) a, (Int16) (a >> 0x10),
(Int16) (a >> 0x20), (Int16) (a >> 0x30)};
}
private static byte[] separate_to_8_byte(Int64 a)
{
return new []{(byte) a, (byte) (a >> 8), (byte) (a >> 0x10),
(byte) (a >> 0x18), (byte) (a >> 0x20), (byte) (a >> 0x28),
(byte) (a >> 0x30), (byte) (a >> 0x38)};
}
public static string to_string(byte[] values)
{
string s = "";
foreach (var val in values)
s += (s == "" ? "" : " ") + val;
return s;
}
public static string to_string(Int16[] values)
{
string s = "";
foreach (var val in values)
s += (s == "" ? "" : " ") + val;
return s;
}
// ---
public static Int64 deconvolution(Int64 a, Int64 b)
{
var large = System.Numerics.BigInteger.Parse(
"1000000000000000000000000000000");
return (Int64)(((
(new System.Numerics.BigInteger(a) * large)
/ new System.Numerics.BigInteger(b))
* 72057594037927936) / large);
}
}
在以下位置尝试此代码:rextester.com/YPKFA14408
输出为:
The convolution of (1 2 3 4 5 6 7 8) with (1 2 3 4 5 6 7 8) is: (1 4 10 20 35 56 84 120)
The deconvolution of (1 4 10 20 35 56 84 120) with (1 2 3 4 5 6 7 8) is: (219 251 194 172 10 94 253 14)
第一行输出正确的演示可以在这里找到:https://oeis.org/A000292
"Online Encyclopedia of Integer Sequences" … "Tetrahedral (or triangular pyramidal) numbers" … "the convolution of the natural numbers with themselves. - Felix Goldberg"
问:提供的代码中的反卷积函数有什么问题,或者我理解的结果应该是什么?
不同的是进位。
将输入视为多项式...
00000101 becomes x^2 + x^0
00000111 becomes x^2 + x^1 + x^0
多项式乘法和卷积是完全相同的操作(设x
为z
-1,延迟的z变换原语.. . 现在乘法毕竟发生在变换域中)
但是算术乘法与多项式乘法不同,因为进位。结果
(x^1 + x^0) * (x^1 + x^0)
是
x^2 + 2 x^1 + x^0
确实是卷积
conv([1 1], [1 1]) = [1 2 1]
但是虽然
0011 * 0011
同样是
0100 + 2 * 0010 + 0001
算术上,2 * 0010
变成0100
,最后的结果
1001
与卷积(多项式乘法)完全不同,因为发生了进位。
运算结果只在x = 2
...时成立,但在卷积x
中必须是延时算子
如果您使用每组 8 位表示一个时间样本的振幅,则会出现相同的效果。一个组内的算术是可以的,但是一旦你有一个跨组边界的进位,卷积和乘法之间的等价性就丢失了。
虽然 "convolutions are multiplications in the frequency domain",但从字面上看,它们似乎也是乘法。例如,如果我将内存中的数字相邻地连接成一种列表:
5: (byte) 00000101
22: (byte) 00010110
7: (byte) 00000111
8: (byte) 00001000
Becomes:
(Int32) 00000101000101100000011100001000
然后将这个结果 list/number 乘以另一个这样的列表,结果是一个列表与另一个列表的卷积。以下 C# 程序对此进行了演示:
using System;
public class Program
{
public static void Main(string[] args)
{
var A = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
var a = combine_to_Int64(A);
var B = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
var b = combine_to_Int64(B);
var c = a * b;
var C = separate_to_8_byte(c);
var d = deconvolution(c, b); // not correct
var D = separate_to_8_byte(d);
Console.WriteLine(
"The convolution of (" + to_string(A) + ") with ("
+ to_string(B) + ") is: (" + to_string(C) + ")");
Console.WriteLine(
"The deconvolution of (" + to_string(C) + ") with ("
+ to_string(B) + ") is: (" + to_string(D) + ")");
}
public static Int64 convolution(Int64 a, Int64 b)
{
return a * b;
}
private static Int64 combine_to_Int64(byte[] n)
{
if (n.Length == 4)
return n[0] + 65536 * n[1] + 4294967296 * n[2] +
281474976710656 * n[3];
else if (n.Length == 8)
return n[0] + 256 * n[1] + 65536 * n[2] + 16777216 * n[3] +
4294967296 * n[4] + 1099511627776 * n[5] +
281474976710656 * n[6] + 72057594037927936 * n[7];
else
throw new ArgumentException();
}
private static Int16[] separate_to_4_Int16(Int64 a)
{
return new []{(Int16) a, (Int16) (a >> 0x10),
(Int16) (a >> 0x20), (Int16) (a >> 0x30)};
}
private static byte[] separate_to_8_byte(Int64 a)
{
return new []{(byte) a, (byte) (a >> 8), (byte) (a >> 0x10),
(byte) (a >> 0x18), (byte) (a >> 0x20), (byte) (a >> 0x28),
(byte) (a >> 0x30), (byte) (a >> 0x38)};
}
public static string to_string(byte[] values)
{
string s = "";
foreach (var val in values)
s += (s == "" ? "" : " ") + val;
return s;
}
public static string to_string(Int16[] values)
{
string s = "";
foreach (var val in values)
s += (s == "" ? "" : " ") + val;
return s;
}
// ---
public static Int64 deconvolution(Int64 a, Int64 b)
{
var large = System.Numerics.BigInteger.Parse(
"1000000000000000000000000000000");
return (Int64)(((
(new System.Numerics.BigInteger(a) * large)
/ new System.Numerics.BigInteger(b))
* 72057594037927936) / large);
}
}
在以下位置尝试此代码:rextester.com/YPKFA14408
输出为:
The convolution of (1 2 3 4 5 6 7 8) with (1 2 3 4 5 6 7 8) is: (1 4 10 20 35 56 84 120)
The deconvolution of (1 4 10 20 35 56 84 120) with (1 2 3 4 5 6 7 8) is: (219 251 194 172 10 94 253 14)
第一行输出正确的演示可以在这里找到:https://oeis.org/A000292
"Online Encyclopedia of Integer Sequences" … "Tetrahedral (or triangular pyramidal) numbers" … "the convolution of the natural numbers with themselves. - Felix Goldberg"
问:提供的代码中的反卷积函数有什么问题,或者我理解的结果应该是什么?
不同的是进位。
将输入视为多项式...
00000101 becomes x^2 + x^0
00000111 becomes x^2 + x^1 + x^0
多项式乘法和卷积是完全相同的操作(设x
为z
-1,延迟的z变换原语.. . 现在乘法毕竟发生在变换域中)
但是算术乘法与多项式乘法不同,因为进位。结果
(x^1 + x^0) * (x^1 + x^0)
是
x^2 + 2 x^1 + x^0
确实是卷积
conv([1 1], [1 1]) = [1 2 1]
但是虽然
0011 * 0011
同样是
0100 + 2 * 0010 + 0001
算术上,2 * 0010
变成0100
,最后的结果
1001
与卷积(多项式乘法)完全不同,因为发生了进位。
运算结果只在x = 2
...时成立,但在卷积x
中必须是延时算子
如果您使用每组 8 位表示一个时间样本的振幅,则会出现相同的效果。一个组内的算术是可以的,但是一旦你有一个跨组边界的进位,卷积和乘法之间的等价性就丢失了。