matlab中fft和ifft函数,matlab中的ifft
在numpy,我们有以下功能:
进口数量
从numpy.fft导入fft2、ifft2、fftshift、ifftshift
我想用R重写这些函数,用R重写fft,就像用python重写fft或fft2一样。同样对于ifft2,我们必须做fft(,逆=T)
现在想知道如何在r中有效地重写fftshift和ifftshift函数(针对矩阵)。
解决方法:
FFT和fftshift背后的概念非常简单。这是我从MathWorks(MATLAB的MATLAB创建者)中提取的数字:
想象你的输入2D矩阵被分成四个象限。象限#1在左上角,象限#2在右上角,象限#3在右下角,象限#4在左下角。对于2D矩阵,默认情况下,fftshift交换第一和第三象限以及第二和第四象限。只需对一个维度执行fftshift,就可以覆盖这种行为。如果你这样做,你会交换所谓的一半空间。如果指定沿行交换(即维度1),矩阵的上半部分将与下半部分交换。如果指定沿列交换(即维2),则右半部分与左半部分交换:
默认情况下,使用fftshift链接按顺序交换大小1和大小2。如果你有一个偶数大小的矩阵,其中行和列都是偶数,那么把矩阵分成四部分并交换它们是非常清楚的。但是,如果矩阵是奇数大小,这取决于您正在查看的语言。比如在MATLAB和Python numpy中,进行切换的位置定义为(r,C)=ceil(rows/2),ceil(cols/2),其中rows和cols是矩阵的行和列。r和c是交换发生的行和列。
对于ifftshift,只需要反转对fftshift执行的操作。因此,默认操作是先交换大小2,然后交换大小1。然而,你必须为奇数大小的矩阵重新定义交换中心的位置。您必须使用floor而不是ceil,因为这可以在执行ffthift后准确地确定半空间的位置,并且您现在正在撤消对原始矩阵的操作。因此,新的交换中心为(r,c)=floor (rows/2),floor (cols/2)。否则,各个维度之间的切换逻辑是相同的——现在只是切换中心发生了变化。
这是我想到的。这些函数采用R中定义的矩阵和第二个可选参数来确定要交换的维度。省略这个操作将执行我刚才谈到的默认象限交换:
fftshift
行
关口
交换向上向下
行数_一半
return(r bind(input _ matrix[((rows _ half 1):rows),(1:cols)],input_matrix[(1:rows_half),(1:cols)])
}
交换_左_右
半栏
return(cbind(input_matrix[1:rows,((cols_half 1):cols)],input _ matrix[1:rows,1:cols_half]))
}
if (dim==-1) {
输入矩阵
返回(swap_left_right(input_matrix))
}
else if (dim==1) {
返回(swap_up_down(input_matrix))
}
else if (dim==2) {
返回(swap_left_right(input_matrix))
}
否则{
停止(“无效尺寸参数”)
}
}
ifftshift
行
关口
交换向上向下
行数_一半
return(r bind(input _ matrix[((rows _ half 1):rows),(1:cols)],input_matrix[(1:rows_half),(1:cols)])
}
交换_左_右
半栏
return(cbind(input_matrix[1:rows,((cols_half 1):cols)],input _ matrix[1:rows,1:cols_half]))
}
if (dim==-1) {
输入矩阵
返回(swap_up_down(input_matrix))
}
else if (dim==1) {
返回(swap_up_down(input_matrix))
}
else if (dim==2) {
返回(swap_left_right(input_matrix))
}
否则{
停止(“无效尺寸参数”)
}
}
在每个函数中,我都定义了一个函数来交换左右两半和上下两半。要交换左半部分和右半部分,只需确定用于执行交换的列,并使用索引通过将这两部分连接在一起创建一个新的矩阵,其中前半部分是右半部分,后半部分是左半部分。当您交换上半部分和下半部分时,您将执行相同的操作,但是要找到正确的行来执行交换。
第二个参数dim可以设置为1或2,以交换相应的尺寸。请注意,fftshift和ifftshift的唯一区别是定义的交换中心和两维交换时的默认操作顺序。其余的代码是相同的。
作为一种演示方式,假设我声明了一个5 x 5的数字矩阵,如下所示:
O
O
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
请注意,矩阵的大小在两个维度上都是奇数。对我们执行ffthift:
P
P
[,1] [,2] [,3] [,4] [,5]
[1,] 19 24 4 9 14
[2,] 20 25 5 10 15
[3,] 16 21 1 6 11
[4,] 17 22 2 7 12
[5,] 18 23 3 8 13
可以看到相应的维度已经互换了。用ifftshift反转这个应该会给我们原始矩阵,它确实:
Q
Q
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
当然,您可以覆盖它并指定要交换的维度,所以假设您只想交换行:
fftshift(O,1)
[,1] [,2] [,3] [,4] [,5]
[1,] 4 9 14 19 24
[2,] 5 10 15 20 25
[3,] 1 6 11 16 21
[4,] 2 7 12 17 22
[5,] 3 8 13 18 23
ifftshift(fftshift(O,1),1)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
请注意,当对大小被交换的矩阵执行ifftshift时,必须使用与使用fftshift时用于交换的大小相同的大小,以确保返回原始矩阵。
我们也可以对第二维空间做同样的事情:
ifftshift(O,2)
[,1] [,2] [,3] [,4] [,5]
[1,] 11 16 21 1 6
[2,] 12 17 22 2 7
[3,] 13 18 23 3 8
[4,] 14 19 24 4 9
[5,] 15 20 25 5 10
ifftshift(fftshift(O,2),2)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
有趣的是,我们可以验证numpy和我们上面讨论的是一样的。这是一个IPython会话:
在[16]中:将numpy作为np导入
In [17]:从numpy.fft导入fftshift,ifftshift
在[18]中:O=NP . shape(NP . arange(1,26),(5,5))。T
在[19]: O
Out[19]:
数组([[ 1,6,11,16,21],
[ 2, 7, 12, 17, 22],
[ 3, 8, 13, 18, 23],
[ 4, 9, 14, 19, 24],
[ 5, 10, 15, 20, 25]])
In [20]: fftshift(O)
Out[20]:
数组([[19,24,4,9,14],
[20, 25, 5, 10, 15],
[16, 21, 1, 6, 11],
[17, 22, 2, 7, 12],
[18, 23, 3, 8, 13]])
在[21]中:ifftshift(fftshift(O))
Out[21]:
数组([[ 1,6,11,16,21],
[ 2, 7, 12, 17, 22],
[ 3, 8, 13, 18, 23],
[ 4, 9, 14, 19, 24],
[ 5, 10, 15, 20, 25]])
从numpy.fft包中导入numpy,fftshift和ifftshift,创建一个2D矩阵,和你在R中定义的例子中看到的一样,然后我们调用fftshift,然后依次调整fftshift和ifftshift,看到我们得到的结果和R代码中看到的一样。
标签:python,r,numpy,fft,ifft
资料来源:https://codeday.me/bug/20190829/1757356.html
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。