Home > Blockchain >  Why do I get a truth value error when doing an nth dimension fast fourier transformation with two ar
Why do I get a truth value error when doing an nth dimension fast fourier transformation with two ar

Time:06-13

I am fairly new to coding but have been put on a project where i am using 'numpy.fft.fftn' for cross correlation. Most of this work is from translating Matlab code over. This is the part of code that I am having trouble with:

def rot90_3D(T):
    T=numpy.flip(numpy.flip(numpy.flip(T,0),1),2);
    return(T)

T_size = [T.shape[0],T.shape[1],T.shape[2]]; I_size = [I.shape[0],I.shape[1],I.shape[2]];
TI=[]
for i in range(0,3,1):
    TI1=T_size[i] I_size[i]
    TI=numpy.append(TI,TI1)
one=numpy.ones((1,3))
outsize = TI - one;
FT = numpy.fft.fftn(rot90_3D(T),outsize);

When I run this cell cell with my input of T being an array of float32 which is (51,51,51) and the values are all between 0 and 1, most of them being decimals something like 0.131866. Yet when I run the cell I get this error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Please let me know what I can do to fix this.

EDIT: Here is the full error message:

Traceback (most recent call last):

  File "C:\Users\Grant\OneDrive\Desktop\SearchParticle Test.py", line 53, in <module>
    FT = numpy.fft.fftn(T2,outsize);

  File "<__array_function__ internals>", line 5, in fftn

  File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 813, in fftn
    return _raw_fftnd(a, s, axes, fft, norm)

  File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 705, in _raw_fftnd
    a = function(a, n=s[ii], axis=axes[ii], norm=norm)

  File "<__array_function__ internals>", line 5, in fft

  File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 214, in fft
    inv_norm = _get_forward_norm(n, norm)

  File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 79, in _get_forward_norm
    if n < 1:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

CodePudding user response:

In [94]: T = np.random.rand(10,10,10)

A more direct way of flipping T:

In [95]: t1 = rot90_3D(T)    
In [96]: t2 = T[::-1,::-1,::-1]    
In [97]: np.allclose(t1,t2)
Out[97]: True

For your outsize:

In [98]: I = np.ones((3,3,3))     # sample

In [99]: T_size = [T.shape[0],T.shape[1],T.shape[2]]; I_size = [I.shape[0],I.shape[1],I.shape[2]];
    ...: TI=[]
    ...: for i in range(0,3,1):
    ...:     TI1=T_size[i] I_size[i]
    ...:     TI=numpy.append(TI,TI1)
    ...: one=numpy.ones((1,3))
    ...: outsize = TI - one;

In [100]: outsize
Out[100]: array([[12., 12., 12.]])

In [101]: T.shape, I.shape
Out[101]: ((10, 10, 10), (3, 3, 3))

Just do:

In [102]: np.array(T.shape) np.array(I.shape)-1
Out[102]: array([12, 12, 12])

T.shape is a tuple; your T_size is a list version of that. Arrays can be added without iteration.

But a list comprehension also does nicely:

In [104]: [i j-1 for i,j in zip(T.shape, I.shape)]
Out[104]: [12, 12, 12]

So far no error. So the problem must be in the fft call.

Here's the full error that you should have shown:

In [105]: numpy.fft.fftn(rot90_3D(T),outsize)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [105], in <cell line: 1>()
----> 1 numpy.fft.fftn(rot90_3D(T),outsize)

File <__array_function__ internals>:5, in fftn(*args, **kwargs)

File ~\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py:815, in fftn(a, s, axes, norm)
    715 @array_function_dispatch(_fftn_dispatcher)
    716 def fftn(a, s=None, axes=None, norm=None):
    717     """
    718     Compute the N-dimensional discrete Fourier Transform.
    719 
   (...)
    813 
    814     """
--> 815     return _raw_fftnd(a, s, axes, fft, norm)

File ~\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py:707, in _raw_fftnd(a, s, axes, function, norm)
    705 itl.reverse()
    706 for ii in itl:
--> 707     a = function(a, n=s[ii], axis=axes[ii], norm=norm)
    708 return a

File <__array_function__ internals>:5, in fft(*args, **kwargs)

File ~\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py:214, in fft(a, n, axis, norm)
    212 if n is None:
    213     n = a.shape[axis]
--> 214 inv_norm = _get_forward_norm(n, norm)
    215 output = _raw_fft(a, n, axis, False, True, inv_norm)
    216 return output

File ~\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py:79, in _get_forward_norm(n, norm)
     78 def _get_forward_norm(n, norm):
---> 79     if n < 1:
     80         raise ValueError(f"Invalid number of FFT data points ({n}) specified.")
     82     if norm is None or norm == "backward":

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Tracing this will take some work, but at the core it's testing n. n should be a number, but for some reason it's an array. What is that n?

I haven't used fft, so am not familiar with the required arguments.

But if I call it with without the outsize, I get a result

In [109]: f = numpy.fft.fftn(rot90_3D(T))
In [110]: f.shape
Out[110]: (10, 10, 10)

So there's something wrong with the way you calculate outsize. When you got the error, did you (re)read the fftn docs - to make sure you use the right arguments?

Glancing at the docs, I deduced that outsize could be a simple list of 3 numbers:

In [111]: f = numpy.fft.fftn(rot90_3D(T), [12,12,12])
In [112]: f.shape
Out[112]: (12, 12, 12)

np.array([12,12,12]) is also ok. But a (1,3) array np.array([[12,12,12]]) produces the error.

When translating MATLAB code, don't try to make everything 2d. numpy arrays can be 1d, and in some cases must be.

  • Related