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

39 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
Edited: Matt J on 23 Nov 2025
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
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
Edited: Matt J on 23 Nov 2025
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
Edited: Paul on 23 Nov 2025
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
  21 Comments
Matt J
Matt J on 3 Dec 2025
Edited: Matt J on 3 Dec 2025
So, just to be clear, I don't judge whether a bug is in play based solely on input/output. I'm judging it also based on how we know the data is processed in each of these cases. We haven't really been able to identify anything improper about how the processing is done when symflag='nonsymmetric' within ifft2.m. There are discrepancies in the outputs of the Case 1 and Case 3 tests, but those appear to arise from normal floating point precision noise.
Conversely, we have identified impropriety in the way symflag='symmetric' is processed when X is 3D or higher and Case 4 exposes that. I consider the bug to be in play in Case 2 as well, because the data is being processed in the same incorrect wasy as in Case 4. Granted, the test in Case 2 doesn't expose the bug - you are again getting agreement within float precision. But that's only because, with an already-symmetric X as input, it's an uninformative test. It doesn't mean the processing is being done properly.
Paul
Paul on 22 Jan 2026 at 17:26
Edited: Paul on 23 Jan 2026 at 20:28
Apparently there's been a bug in ifft2 since forever, and it's been fixed in 2025b Update 3:
That's the version that we're running here (despite what hovering over the Run button indicates or the Ran In indicator)
matlabRelease
ans =
matlabRelease with properties: Release: "R2025b" Stage: "release" Update: 3 Date: 29-Dec-2025
so I guess we can test some of the examples from this thread.
percentError=@(a,b) norm(a(:)-b(:),inf)/norm(b(:),inf)*100;
rng(12345);
format short e
Case 1: symmetric transform, call with non-symmetric, 2D doesn't match ND slice, but they're close
x = rand(10);
X = fft2(x); % symmetric transform of real signal
x1 = ifft2(X,'nonsymmetric');
x2 = ifft2(cat(3,X,X),'nonsymmetric');
[percentError(x1,x2(:,:,1)),percentError(x,x1),percentError(x,x2(:,:,1))]
ans = 1×3
1.0e+00 * 2.2338e-14 3.3507e-14 2.5130e-14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Case 2: symmetric transform, call with symmetric, 2D doesn't match ND slice, but they're close
x1 = ifft2(X,'symmetric');
x2 = ifft2(cat(3,X,X),'symmetric');
[percentError(x1,x2(:,:,1)),percentError(x,x1),percentError(x,x2(:,:,1))]
ans = 1×3
1.0e+00 * 2.2338e-14 3.3507e-14 2.5130e-14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Case 3: nonsymmetric transform, call with nonsymmetric, 2D doesn't match ND slice, but they're close
x = rand(10) + 1j*rand(10);
X = fft2(x); % nonsymmetric transform of complex signal
x1 = ifft2(X,'nonsymmetric');
x2 = ifft2(cat(3,X,X),'nonsymmetric');
[percentError(x1,x2(:,:,1)),percentError(x,x1),percentError(x,x2(:,:,1))]
ans = 1×3
1.0e+00 * 3.5004e-14 3.7967e-14 2.8840e-14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Case 4: nonsymmetric transform, call with symmetric, 2D now almost nearly matches ND slice, but not exact.
x1 = ifft2(X,'symmetric');
x2 = ifft2(cat(3,X,X),'symmetric');
[percentError(x1,x2(:,:,1))]
ans =
3.4856e-14
I think the reason that the match isn't exact between 2D and ND-slice in Case 4 is that 2D uses ifftn and ND still uses two calls to ifft.
However, their solution, as best I can tell, is to actually modify the ND input to enforce each page is symmetric (presumably only when 'symmetric' is set) prior to the double call to ifft. I wonder if that's always the most efficient approach.

Sign in to comment.

Categories

Find more on Linear Algebra in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!