def test_dft_call(impl): # 2d, complex, all ones and random back & forth shape = (4, 5) dft_dom = odl.discr_sequence_space(shape, dtype="complex64") dft = DiscreteFourierTransform(domain=dft_dom, impl=impl) idft = DiscreteFourierTransformInverse(range=dft_dom, impl=impl) assert dft.domain == idft.range assert dft.range == idft.domain one = dft.domain.one() one_dft1 = dft(one, flags=("FFTW_ESTIMATE",)) one_dft2 = dft.inverse.inverse(one, flags=("FFTW_ESTIMATE",)) one_dft3 = dft.adjoint.adjoint(one, flags=("FFTW_ESTIMATE",)) true_dft = [[20, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # along all axes by default assert np.allclose(one_dft1, true_dft) assert np.allclose(one_dft2, true_dft) assert np.allclose(one_dft3, true_dft) one_idft1 = idft(one_dft1, flags=("FFTW_ESTIMATE",)) one_idft2 = dft.inverse(one_dft1, flags=("FFTW_ESTIMATE",)) one_idft3 = dft.adjoint(one_dft1, flags=("FFTW_ESTIMATE",)) assert np.allclose(one_idft1, one) assert np.allclose(one_idft2, one) assert np.allclose(one_idft3, one) rand_arr = noise_element(dft_dom) rand_arr_dft = dft(rand_arr, flags=("FFTW_ESTIMATE",)) rand_arr_idft = idft(rand_arr_dft, flags=("FFTW_ESTIMATE",)) assert (rand_arr_idft - rand_arr).norm() < 1e-6 # 2d, halfcomplex, first axis shape = (4, 5) axes = 0 dft_dom = odl.discr_sequence_space(shape, dtype="float32") dft = DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, axes=axes) idft = DiscreteFourierTransformInverse(range=dft_dom, impl=impl, halfcomplex=True, axes=axes) assert dft.domain == idft.range assert dft.range == idft.domain one = dft.domain.one() one_dft = dft(one, flags=("FFTW_ESTIMATE",)) true_dft = [[4, 4, 4, 4, 4], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # transform axis shortened assert np.allclose(one_dft, true_dft) one_idft1 = idft(one_dft, flags=("FFTW_ESTIMATE",)) one_idft2 = dft.inverse(one_dft, flags=("FFTW_ESTIMATE",)) assert np.allclose(one_idft1, one) assert np.allclose(one_idft2, one) rand_arr = noise_element(dft_dom) rand_arr_dft = dft(rand_arr, flags=("FFTW_ESTIMATE",)) rand_arr_idft = idft(rand_arr_dft, flags=("FFTW_ESTIMATE",)) assert (rand_arr_idft - rand_arr).norm() < 1e-6
def test_dft_sign(impl): # Test if the FT sign behaves as expected, i.e. that the FT with sign # '+' and '-' have same real parts and opposite imaginary parts. # 2d, complex, all ones and random back & forth shape = (4, 5) dft_dom = odl.discr_sequence_space(shape, dtype='complex64') dft_minus = DiscreteFourierTransform(domain=dft_dom, impl=impl, sign='-') dft_plus = DiscreteFourierTransform(domain=dft_dom, impl=impl, sign='+') arr = dft_dom.element([[0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]) arr_dft_minus = dft_minus(arr, flags=('FFTW_ESTIMATE', )) arr_dft_plus = dft_plus(arr, flags=('FFTW_ESTIMATE', )) assert all_almost_equal(arr_dft_minus.real, arr_dft_plus.real) assert all_almost_equal(arr_dft_minus.imag, -arr_dft_plus.imag) assert all_almost_equal(dft_minus.inverse(arr_dft_minus), arr) assert all_almost_equal(dft_plus.inverse(arr_dft_plus), arr) assert all_almost_equal(dft_minus.inverse.inverse(arr), dft_minus(arr)) assert all_almost_equal(dft_plus.inverse.inverse(arr), dft_plus(arr)) # 2d, halfcomplex, first axis shape = (4, 5) axes = (0, ) dft_dom = odl.discr_sequence_space(shape, dtype='float32') arr = dft_dom.element([[0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]) dft = DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, sign='-', axes=axes) arr_dft_minus = dft(arr, flags=('FFTW_ESTIMATE', )) arr_idft_minus = dft.inverse(arr_dft_minus, flags=('FFTW_ESTIMATE', )) assert all_almost_equal(arr_idft_minus, arr) with pytest.raises(ValueError): DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, sign='+', axes=axes)
def test_dft_sign(impl): # Test if the FT sign behaves as expected, i.e. that the FT with sign # '+' and '-' have same real parts and opposite imaginary parts. # 2d, complex, all ones and random back & forth shape = (4, 5) dft_dom = odl.discr_sequence_space(shape, dtype="complex64") dft_minus = DiscreteFourierTransform(domain=dft_dom, impl=impl, sign="-") dft_plus = DiscreteFourierTransform(domain=dft_dom, impl=impl, sign="+") arr = dft_dom.element([[0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]) arr_dft_minus = dft_minus(arr, flags=("FFTW_ESTIMATE",)) arr_dft_plus = dft_plus(arr, flags=("FFTW_ESTIMATE",)) assert all_almost_equal(arr_dft_minus.real, arr_dft_plus.real) assert all_almost_equal(arr_dft_minus.imag, -arr_dft_plus.imag) assert all_almost_equal(dft_minus.inverse(arr_dft_minus), arr) assert all_almost_equal(dft_plus.inverse(arr_dft_plus), arr) assert all_almost_equal(dft_minus.inverse.inverse(arr), dft_minus(arr)) assert all_almost_equal(dft_plus.inverse.inverse(arr), dft_plus(arr)) # 2d, halfcomplex, first axis shape = (4, 5) axes = (0,) dft_dom = odl.discr_sequence_space(shape, dtype="float32") arr = dft_dom.element([[0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]) dft = DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, sign="-", axes=axes) arr_dft_minus = dft(arr, flags=("FFTW_ESTIMATE",)) arr_idft_minus = dft.inverse(arr_dft_minus, flags=("FFTW_ESTIMATE",)) assert all_almost_equal(arr_idft_minus, arr) with pytest.raises(ValueError): DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, sign="+", axes=axes)
def test_dft_call(impl): # 2d, complex, all ones and random back & forth shape = (4, 5) dft_dom = odl.discr_sequence_space(shape, dtype='complex64') dft = DiscreteFourierTransform(domain=dft_dom, impl=impl) idft = DiscreteFourierTransformInverse(range=dft_dom, impl=impl) assert dft.domain == idft.range assert dft.range == idft.domain one = dft.domain.one() one_dft1 = dft(one, flags=('FFTW_ESTIMATE', )) one_dft2 = dft.inverse.inverse(one, flags=('FFTW_ESTIMATE', )) one_dft3 = dft.adjoint.adjoint(one, flags=('FFTW_ESTIMATE', )) true_dft = [ [20, 0, 0, 0, 0], # along all axes by default [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ] assert np.allclose(one_dft1, true_dft) assert np.allclose(one_dft2, true_dft) assert np.allclose(one_dft3, true_dft) one_idft1 = idft(one_dft1, flags=('FFTW_ESTIMATE', )) one_idft2 = dft.inverse(one_dft1, flags=('FFTW_ESTIMATE', )) one_idft3 = dft.adjoint(one_dft1, flags=('FFTW_ESTIMATE', )) assert np.allclose(one_idft1, one) assert np.allclose(one_idft2, one) assert np.allclose(one_idft3, one) rand_arr = noise_element(dft_dom) rand_arr_dft = dft(rand_arr, flags=('FFTW_ESTIMATE', )) rand_arr_idft = idft(rand_arr_dft, flags=('FFTW_ESTIMATE', )) assert (rand_arr_idft - rand_arr).norm() < 1e-6 # 2d, halfcomplex, first axis shape = (4, 5) axes = 0 dft_dom = odl.discr_sequence_space(shape, dtype='float32') dft = DiscreteFourierTransform(domain=dft_dom, impl=impl, halfcomplex=True, axes=axes) idft = DiscreteFourierTransformInverse(range=dft_dom, impl=impl, halfcomplex=True, axes=axes) assert dft.domain == idft.range assert dft.range == idft.domain one = dft.domain.one() one_dft = dft(one, flags=('FFTW_ESTIMATE', )) true_dft = [ [4, 4, 4, 4, 4], # transform axis shortened [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ] assert np.allclose(one_dft, true_dft) one_idft1 = idft(one_dft, flags=('FFTW_ESTIMATE', )) one_idft2 = dft.inverse(one_dft, flags=('FFTW_ESTIMATE', )) assert np.allclose(one_idft1, one) assert np.allclose(one_idft2, one) rand_arr = noise_element(dft_dom) rand_arr_dft = dft(rand_arr, flags=('FFTW_ESTIMATE', )) rand_arr_idft = idft(rand_arr_dft, flags=('FFTW_ESTIMATE', )) assert (rand_arr_idft - rand_arr).norm() < 1e-6