diff --git a/nifty/field.py b/nifty/field.py index 956e072fcfcdb986c96078b22250b0e77a2c6177..2470af1c35b4549e3e5399751e179ba685dc5b0d 100644 --- a/nifty/field.py +++ b/nifty/field.py @@ -332,10 +332,9 @@ class Field(object): if len(spaces) == ndom: return dobj.vdot(self.val, x.val) - raise NotImplementedError # If we arrive here, we have to do a partial dot product. # For the moment, do this the explicit, non-optimized way - return (self.conjugate()*x).integrate(spaces=spaces) + return (self.conjugate()*x).sum(spaces=spaces) def norm(self): """ Computes the L2-norm of the field values. diff --git a/nifty/operators/fft_operator.py b/nifty/operators/fft_operator.py index 79d41a7f8ea3919614e0dabfa396950556bbe725..4fc3128ac92b343c9b9dff53bd958c9a601507f2 100644 --- a/nifty/operators/fft_operator.py +++ b/nifty/operators/fft_operator.py @@ -85,10 +85,10 @@ class FFTOperator(LinearOperator): def apply(self, x, mode): self._check_input(x, mode) if np.issubdtype(x.dtype, np.complexfloating): - res = (self._trafo.transform(x.real) + - 1j * self._trafo.transform(x.imag)) + res = (self._trafo.apply(x.real, mode) + + 1j * self._trafo.apply(x.imag, mode)) else: - res = self._trafo.transform(x) + res = self._trafo.apply(x, mode) return res @property diff --git a/nifty/operators/fft_operator_support.py b/nifty/operators/fft_operator_support.py index b8e3a9a8afde712c3fd2a3313093eb32c3cbe6fb..1fc687570a1e67a54bc75ac0ee2d4af30862fd7f 100644 --- a/nifty/operators/fft_operator_support.py +++ b/nifty/operators/fft_operator_support.py @@ -22,6 +22,7 @@ from .. import utilities from .. import dobj from ..field import Field from ..spaces.gl_space import GLSpace +from .linear_operator import LinearOperator class Transformation(object): @@ -41,14 +42,14 @@ class RGRGTransformation(Transformation): # apply effectively a factor of 1/sqrt(N) to the field. # BUT: the pixel volumes of the domain and codomain are different. # Hence, in order to produce the same scalar product, power==1. - self.fct_p2h = pdom[space].scalar_dvol() - self.fct_h2p = 1./(pdom[space].scalar_dvol()*hdom[space].dim) + self.fct_noninverse = pdom[space].scalar_dvol() + self.fct_inverse = 1./(pdom[space].scalar_dvol()*hdom[space].dim) @property def unitary(self): return True - def transform(self, x): + def apply(self, x, mode): """ RG -> RG transform method. @@ -125,7 +126,11 @@ class RGRGTransformation(Transformation): ldat = ldat.real+ldat.imag tmp = dobj.from_local_data(tmp.shape, ldat, distaxis=oldax) Tval = Field(tdom, tmp) - fct = self.fct_p2h if p2h else self.fct_h2p + if (mode == LinearOperator.TIMES or + mode == LinearOperator.ADJOINT_TIMES): + fct = self.fct_noninverse + else: + fct = self.fct_inverse if fct != 1: Tval *= fct @@ -152,14 +157,14 @@ class SphericalTransformation(Transformation): return False def _slice_p2h(self, inp): - rr = self.sjob.map2alm(inp) + rr = self.sjob.alm2map_adjoint(inp) assert len(rr) == ((self.mmax+1)*(self.mmax+2))//2 + \ (self.mmax+1)*(self.lmax-self.mmax) res = np.empty(2*len(rr)-self.lmax-1, dtype=rr[0].real.dtype) res[0:self.lmax+1] = rr[0:self.lmax+1].real res[self.lmax+1::2] = np.sqrt(2)*rr[self.lmax+1:].real res[self.lmax+2::2] = np.sqrt(2)*rr[self.lmax+1:].imag - return res + return res*(np.sqrt(4*np.pi)/inp.size) def _slice_h2p(self, inp): res = np.empty((len(inp)+self.lmax+1)//2, dtype=(inp[0]*1j).dtype) @@ -168,9 +173,10 @@ class SphericalTransformation(Transformation): res[0:self.lmax+1] = inp[0:self.lmax+1] res[self.lmax+1:] = np.sqrt(0.5)*(inp[self.lmax+1::2] + 1j*inp[self.lmax+2::2]) - return self.sjob.alm2map(res) + res = self.sjob.alm2map(res) + return res*(np.sqrt(4*np.pi)/res.size) - def transform(self, x): + def apply(self, x, mode): axes = x.domain.axes[self.space] axis = axes[0] tval = x.val diff --git a/nifty/operators/fft_smoothing_operator.py b/nifty/operators/fft_smoothing_operator.py index 8312b5c91fa87af68aee254e0bd71768d61ae839..4e6c86ca7b38f79a937d49990b731f2f928f27b7 100644 --- a/nifty/operators/fft_smoothing_operator.py +++ b/nifty/operators/fft_smoothing_operator.py @@ -22,4 +22,4 @@ def FFTSmoothingOperator(domain, sigma, space=None): ddom = list(domain) ddom[space] = codomain diag = DiagonalOperator(kernel, ddom, space) - return FFT.adjoint*diag*FFT + return FFT.inverse*diag*FFT diff --git a/test/test_field.py b/test/test_field.py index c2a68bb73b76a32b1fd948b670762e64d02ce8df..22efbf9ca2813ee2a35d64cc05ce711ed1826456 100644 --- a/test/test_field.py +++ b/test/test_field.py @@ -135,5 +135,4 @@ class Test_Functionality(unittest.TestCase): x2 = ift.RGSpace((150,)) m = ift.Field((x1, x2), val=.5) res = m.vdot(m, spaces=1) - assert_allclose(ift.dobj.to_global_data(res.val), - ift.dobj.to_global_data(ift.Field(x1, val=.25).val)) + assert_allclose(ift.dobj.to_global_data(res.val), 37.5) diff --git a/test/test_operators/test_fft_operator.py b/test/test_operators/test_fft_operator.py index 1c6f55a3bbdd45b5c727b83c9129f90e9e109537..91c6732923b8e99e6bbc061ce13b5b838669d5b3 100644 --- a/test/test_operators/test_fft_operator.py +++ b/test/test_operators/test_fft_operator.py @@ -44,7 +44,7 @@ class FFTOperatorTests(unittest.TestCase): np.random.seed(16) inp = ift.Field.from_random(domain=a, random_type='normal', std=7, mean=3, dtype=itp) - out = fft.adjoint_times(fft.times(inp)) + out = fft.inverse_times(fft.times(inp)) assert_allclose(ift.dobj.to_global_data(inp.val), ift.dobj.to_global_data(out.val), rtol=tol, atol=tol) @@ -60,7 +60,7 @@ class FFTOperatorTests(unittest.TestCase): inp = ift.Field.from_random(domain=a, random_type='normal', std=7, mean=3, dtype=itp) - out = fft.adjoint_times(fft.times(inp)) + out = fft.inverse_times(fft.times(inp)) assert_allclose(ift.dobj.to_global_data(inp.val), ift.dobj.to_global_data(out.val), rtol=tol, atol=tol) @@ -74,7 +74,7 @@ class FFTOperatorTests(unittest.TestCase): inp = ift.Field.from_random(domain=(a1, a2, a3), random_type='normal', std=7, mean=3, dtype=dtype) - out = fft.adjoint_times(fft.times(inp)) + out = fft.inverse_times(fft.times(inp)) assert_allclose(ift.dobj.to_global_data(inp.val), ift.dobj.to_global_data(out.val), rtol=tol, atol=tol) @@ -87,7 +87,7 @@ class FFTOperatorTests(unittest.TestCase): fft = ift.FFTOperator(domain=a, target=b) inp = ift.Field.from_random(domain=a, random_type='normal', std=7, mean=3, dtype=tp) - out = fft.adjoint_times(fft.times(inp)) + out = fft.inverse_times(fft.times(inp)) assert_allclose(ift.dobj.to_global_data(inp.val), ift.dobj.to_global_data(out.val), rtol=tol, atol=tol) @@ -99,7 +99,7 @@ class FFTOperatorTests(unittest.TestCase): fft = ift.FFTOperator(domain=a, target=b) inp = ift.Field.from_random(domain=a, random_type='normal', std=1, mean=0, dtype=tp) - out = fft.adjoint_times(fft.times(inp)) + out = fft.inverse_times(fft.times(inp)) assert_allclose(ift.dobj.to_global_data(inp.val), ift.dobj.to_global_data(out.val), rtol=1e-3, atol=1e-1)