为什么不(线性地)通过矩阵乘法对矩阵进行插值?
Why not (linearly) interpolate a matrix by matrix multiplication?
我是一名学习线性代数的数学本科生。新闻中最近有一个法庭案件否认了一些视频证据,因为镜头被放大了(数据被插值,它“创造了新的像素”)。这让我开始思考,我将如何对矩阵进行线性插值?
我调查了一下,只能找到使用嵌套 for 循环的算法,没有涉及太多线性代数。这让我很惊讶,因为我认为像矩阵乘法这样的操作更有效率。
最终我想出了一个更简单(也更令人满意!)的方法来用线性代数插值矩阵(最近邻和线性 - 到目前为止)。
(基本上,如果你有一个 mxn 矩阵 A,那么你构造两个非常简单的矩阵:一个 (2m-1)xm 矩阵 L 和一个 nx(2n-1) 矩阵 R,并将它们相乘 L * A * R 以获得具有内插行和列的 (2m-1)x(2n-1) 矩阵。设计 L 和 R 既有趣又简单。)
那么为什么程序员不使用矩阵乘法来对矩阵进行插值呢?理论上,与嵌套 for 循环相比,显卡不应该使这个计算变得非常快吗?
或者也许程序员已经这样做了,但是因为它太明显了,所以发布的信息不多?
谢谢 :D
编辑:似乎我使用嵌套循环而不是矩阵乘法的松散措辞引起了很多混乱。我并不是要暗示 GPU 不循环。我只是说那部分会被抽象到某个库或 GPU 本身后面。好的软件就是这样组合它的功能的。此外,直接通过嵌套循环对其进行编程会丧失矩阵数学算法或 GPU 的优化。
矩阵乘积的算法是否使用嵌套 for 循环实际上是无关紧要的。也许该算法使用递归函数。也许它使用了一些有效但违反直觉的 hack,比如 DOOM 的平方反比函数。这并不重要,这个小小的歧义使大部分讨论脱轨是愚蠢的。
事实证明,我的理解大部分(完全?)正确。 GPU 更适合矩阵数学,但仅适用于非常大的矩阵。
我的问题得到了彻底的回答。 FFT 比 O(n^3) 快得多。我强烈建议您阅读@datenwolf
的回答及其评论
I figured out how a much simpler…
好吧,您刚刚用矩阵-矩阵乘法描述了卷积。是的,这有效。但是它很昂贵,而且数值不稳定,因为它会累积大量的浮点舍入误差。
So why don't programmers use matrix multiplication to interpolate matrices?
因为效率低下。矩阵乘法复杂度 (N³).
一种更有效,同时也“完美”(在信号处理意义上)的方法是执行前向快速傅立叶变换,复杂度 (N·log(N) ),将频谱零填充到所需的输出分辨率,并对其执行 inverse FFT,复杂度再次为 (N·log(N)) ,所以总复杂度为(2(N·log(N)))。 Big-notation省略了常数因子,所以复杂度为(N·log(N)).
其基础数学是 Convolution theorem。
这个远,far,FAR比矩阵的(N³)好乘法。所以这就是为什么我们不在那里使用矩阵乘法的原因。
如果你做一个简单的零填充,你就是在用 sin(x)/x 内核做插值。但是通过将频谱与不同插值内核的频谱相乘,您可以通过这种方式实现您想要的任何类型的插值。
houldn't graphics cards make this a blazing fast calculation when compared to nested for loops?
GPU 具有内置的线性插值器,作为其纹理采样器单元硬件的一部分,其性能优于任何软件实现。
我是一名学习线性代数的数学本科生。新闻中最近有一个法庭案件否认了一些视频证据,因为镜头被放大了(数据被插值,它“创造了新的像素”)。这让我开始思考,我将如何对矩阵进行线性插值?
我调查了一下,只能找到使用嵌套 for 循环的算法,没有涉及太多线性代数。这让我很惊讶,因为我认为像矩阵乘法这样的操作更有效率。
最终我想出了一个更简单(也更令人满意!)的方法来用线性代数插值矩阵(最近邻和线性 - 到目前为止)。
(基本上,如果你有一个 mxn 矩阵 A,那么你构造两个非常简单的矩阵:一个 (2m-1)xm 矩阵 L 和一个 nx(2n-1) 矩阵 R,并将它们相乘 L * A * R 以获得具有内插行和列的 (2m-1)x(2n-1) 矩阵。设计 L 和 R 既有趣又简单。)
那么为什么程序员不使用矩阵乘法来对矩阵进行插值呢?理论上,与嵌套 for 循环相比,显卡不应该使这个计算变得非常快吗?
或者也许程序员已经这样做了,但是因为它太明显了,所以发布的信息不多?
谢谢 :D
编辑:似乎我使用嵌套循环而不是矩阵乘法的松散措辞引起了很多混乱。我并不是要暗示 GPU 不循环。我只是说那部分会被抽象到某个库或 GPU 本身后面。好的软件就是这样组合它的功能的。此外,直接通过嵌套循环对其进行编程会丧失矩阵数学算法或 GPU 的优化。
矩阵乘积的算法是否使用嵌套 for 循环实际上是无关紧要的。也许该算法使用递归函数。也许它使用了一些有效但违反直觉的 hack,比如 DOOM 的平方反比函数。这并不重要,这个小小的歧义使大部分讨论脱轨是愚蠢的。
事实证明,我的理解大部分(完全?)正确。 GPU 更适合矩阵数学,但仅适用于非常大的矩阵。
我的问题得到了彻底的回答。 FFT 比 O(n^3) 快得多。我强烈建议您阅读@datenwolf
的回答及其评论I figured out how a much simpler…
好吧,您刚刚用矩阵-矩阵乘法描述了卷积。是的,这有效。但是它很昂贵,而且数值不稳定,因为它会累积大量的浮点舍入误差。
So why don't programmers use matrix multiplication to interpolate matrices?
因为效率低下。矩阵乘法复杂度 (N³).
一种更有效,同时也“完美”(在信号处理意义上)的方法是执行前向快速傅立叶变换,复杂度 (N·log(N) ),将频谱零填充到所需的输出分辨率,并对其执行 inverse FFT,复杂度再次为 (N·log(N)) ,所以总复杂度为(2(N·log(N)))。 Big-notation省略了常数因子,所以复杂度为(N·log(N)).
其基础数学是 Convolution theorem。
这个远,far,FAR比矩阵的(N³)好乘法。所以这就是为什么我们不在那里使用矩阵乘法的原因。
如果你做一个简单的零填充,你就是在用 sin(x)/x 内核做插值。但是通过将频谱与不同插值内核的频谱相乘,您可以通过这种方式实现您想要的任何类型的插值。
houldn't graphics cards make this a blazing fast calculation when compared to nested for loops?
GPU 具有内置的线性插值器,作为其纹理采样器单元硬件的一部分,其性能优于任何软件实现。