effects of ifft2(x, 'symmetric') while x is not conjugate symmetric

80 views (last 30 days)
Hi all,
I understand that 'symmetric' in ifft2 assumes data is conjugate symmetric and will output real values, but I want to know how exactly is this done. Specifically:
  1. with 'symmetric', will only half of the data be used or still the whole matrix is used, but just output real values?
  2. if x is not conjugate symmetric but I still pass in 'symmetric', what will happen?
Thanks in advance.

Accepted Answer

Matt J
Matt J on 23 Nov 2025 at 1:44
Edited: Matt J on 23 Nov 2025 at 1:45
When you specify "symmetric", the upper half of the fft input array is ignored, e.g.
x=ones(1,7);
ifft(x)
ans = 1×7
1.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
x(5:end)=rand(1,3); %write random junk into the upper half of x
ifft(x)
ans =
0.8258 + 0.0000i 0.0750 + 0.0982i -0.0516 - 0.0461i 0.0637 + 0.1255i 0.0637 - 0.1255i -0.0516 + 0.0461i 0.0750 - 0.0982i
ifft(x,'symmetric')
ans = 1×7
1.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  4 Comments
Paul
Paul on 23 Nov 2025 at 2:55
I don't think that's true for the rows that aren't in the first column.
X = ifft2(rand(10));
x1 = ifft2(X,'symmetric');
X(end,3) = 0;
x2 = ifft2(X,'symmetric');
isequal(x1,x2)
ans = logical
0
Matt J
Matt J on 23 Nov 2025 at 14:19
Edited: Matt J on 23 Nov 2025 at 14:37
Yep, my bad. In higher dimensions, conjugate symmetry means the image is symmetric across the origin. So, if you view the array after fftshift(), the cells it would be using are the right half, minus half of one of the DC axes. In other words, it needs cells from two quadrants to cover the whole array by symmetry, and also only the non-negative DC axes are needed.
If you re-organize this in terms of the original ordering of X(i,j) it means the cells that can be discarded are the light-shaded ones below, which is consistent with what @Paul found in his tests:

Sign in to comment.

More Answers (1)

Paul
Paul on 23 Nov 2025 at 2:24
Edited: Paul on 23 Nov 2025 at 16:44
It appears that only portions of the input matrix are used when 'symmetric' is specified on input to ifft2 and the input is 2D
rng(100);
X = rand(10,12) + 1j*rand(10,12); % non-symmetric input
x1 = ifft2(X,'symmetric');
X(:,8:12) = 0; % zero out the entire right side
X(7:10,1) = 0; % zero out the top half of the first column
x2 = ifft2(X,'symmetric');
isequal(x1,x2)
ans = logical
1
  8 Comments
Paul
Paul about 3 hours ago
Edited: Paul about 1 hour ago
I tried my hand at a basic function that computes the the 2D IFFT with ifftn on each slice of an N-D array
rng(100);
x = rand(24,23,32,25);
X = fft2(x);
x1 = newifft2(X);
norm(x-x1,'fro')
ans = 1.1307e-13
x2 = newifft2(X,'symmetric');
norm(x-x2,'fro')
ans = 1.1279e-13
t1 = timeit(@() ifft2(X)) % 2x-ifft on N-D array
t1 = 0.0013
t2 = timeit(@() newifft2(X)) % ifftn on each 2D slice
t2 = 0.0194
t2/t1
ans = 15.1649
t1 = timeit(@() ifft2(X,'symmetric')) % 2x-ifft on N-D array
t1 = 0.0012
t2 = timeit(@() newifft2(X,'symmetric')) % ifftn on each 2D slice
t2 = 0.0211
t2/t1
ans = 17.4536
function x = newifft2(X,symflag)
if nargin == 1
symflag = 'nonsymmetric';
end
d = size(X);
indices = arrayfun(@(d) {ones(1,d)},d);
C = mat2cell(X,d(1),d(2),indices{3:end});
x = cellfun(@(C) ifftn(C,symflag),C,'uni',false);
x = cell2mat(x);
end
Matt J
Matt J about 5 hours ago
Edited: Matt J 9 minutes ago
Here's another attempt. It seems to improve upon the loop, if nothing else.
clc,rng(100);
X = fft2(rand(41,70,60,10));
x1 = ifft2nLoop(X,'symmetric');
x2= ifft2n(X,'symmetric');
percentDiff = norm(x1-x2,'fro')/norm(x1,'fro')*100
percentDiff = 3.5485e-14
t0 = timeit(@() ifft2(X,'symmetric') ) %wrong result
t0 = 0.0049
t1 = timeit(@() ifft2nLoop(X,'symmetric')) % ifftn on each 2D slice
t1 = 0.0940
t2 = timeit(@() ifft2n(X,'symmetric') ) %proposed
t2 = 0.0155
t2/t0
ans = 3.1307
t2/t1
ans = 0.1645
function x = ifft2n(X,symflag)
arguments
X
symflag='nonsymmetric';
end
if strcmp(symflag,'symmetric')
xsiz=size(X);
[m,n,p]=size(X);
mn=m*n;
I=reshape(1:mn,m,n);
Q=round(fft2(ifft2(I,'symmetric')));
msk=(Q~=I);
X=reshape(X,mn,p);
X=X(Q,:);
X(msk,:)=conj(X(msk,:));
X(1,:)=real(X(1,:));
X=reshape(X,xsiz);
end
x=ifft2( X,symflag);
end
function Y=ifft2nLoop(X,varargin)
%Computes intended ifft2 on a n-D input array X by looping
[~,~,n]=size(X);
Y=X;
for i=1:n %loop over 3D slices, apply ifft2 to each slice
Y(:,:,i)=ifft2(X(:,:,i),varargin{:});
end
end

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!