diff --git a/nifty/field.py b/nifty/field.py index 4999185f3510e0af0e26a7be612bb3006fefc167..a46e36cd42f3922ad7f467410a50c4cadcfcca5f 100644 --- a/nifty/field.py +++ b/nifty/field.py @@ -612,39 +612,47 @@ class Field(Loggable, Versionable, object): # correct variance if preserve_gaussian_variance: + assert issubclass(val.dtype.type, np.complexfloating),\ + "complex input field is needed here" h *= np.sqrt(2) a *= np.sqrt(2) - if not issubclass(val.dtype.type, np.complexfloating): - # in principle one must not correct the variance for the fixed - # points of the hermitianization. However, for a complex field - # the input field loses half of its power at its fixed points - # in the `hermitian` part. Hence, here a factor of sqrt(2) is - # also necessary! - # => The hermitianization can be done on a space level since - # either nothing must be done (LMSpace) or ALL points need a - # factor of sqrt(2) - # => use the preserve_gaussian_variance flag in the - # hermitian_decomposition method above. - - # This code is for educational purposes: - fixed_points = [domain[i].hermitian_fixed_points() - for i in spaces] - fixed_points = [[fp] if fp is None else fp - for fp in fixed_points] - - for product_point in itertools.product(*fixed_points): - slice_object = np.array((slice(None), )*len(val.shape), - dtype=np.object) - for i, sp in enumerate(spaces): - point_component = product_point[i] - if point_component is None: - point_component = slice(None) - slice_object[list(domain_axes[sp])] = point_component - - slice_object = tuple(slice_object) - h[slice_object] /= np.sqrt(2) - a[slice_object] /= np.sqrt(2) +# The code below should not be needed in practice, since it would +# only ever be called when hermitianizing a purely real field. +# However it might be of educational use and keep us from forgetting +# how these things are done ... + +# if not issubclass(val.dtype.type, np.complexfloating): +# # in principle one must not correct the variance for the fixed +# # points of the hermitianization. However, for a complex field +# # the input field loses half of its power at its fixed points +# # in the `hermitian` part. Hence, here a factor of sqrt(2) is +# # also necessary! +# # => The hermitianization can be done on a space level since +# # either nothing must be done (LMSpace) or ALL points need a +# # factor of sqrt(2) +# # => use the preserve_gaussian_variance flag in the +# # hermitian_decomposition method above. +# +# # This code is for educational purposes: +# fixed_points = [domain[i].hermitian_fixed_points() +# for i in spaces] +# fixed_points = [[fp] if fp is None else fp +# for fp in fixed_points] +# +# for product_point in itertools.product(*fixed_points): +# slice_object = np.array((slice(None), )*len(val.shape), +# dtype=np.object) +# for i, sp in enumerate(spaces): +# point_component = product_point[i] +# if point_component is None: +# point_component = slice(None) +# slice_object[list(domain_axes[sp])] = point_component +# +# slice_object = tuple(slice_object) +# h[slice_object] /= np.sqrt(2) +# a[slice_object] /= np.sqrt(2) + return (h, a) def _spec_to_rescaler(self, spec, result_list, power_space_index): diff --git a/nifty/spaces/rg_space/rg_space.py b/nifty/spaces/rg_space/rg_space.py index 4243fc28953b7220b11d09b1c76a3e392976d930..8f70ccf27a3c77c875abdaa1396a7c9860eaef85 100644 --- a/nifty/spaces/rg_space/rg_space.py +++ b/nifty/spaces/rg_space/rg_space.py @@ -100,23 +100,26 @@ class RGSpace(Space): self._distances = self._parse_distances(distances) self._zerocenter = self._parse_zerocenter(zerocenter) - def hermitian_fixed_points(self): - dimensions = len(self.shape) - mid_index = np.array(self.shape)//2 - ndlist = [1]*dimensions - for k in range(dimensions): - if self.shape[k] % 2 == 0: - ndlist[k] = 2 - ndlist = tuple(ndlist) - fixed_points = [] - for index in np.ndindex(ndlist): - for k in range(dimensions): - if self.shape[k] % 2 != 0 and self.zerocenter[k]: - index = list(index) - index[k] = 1 - index = tuple(index) - fixed_points += [tuple(index * mid_index)] - return fixed_points +# This code is unused but may be useful to keep around if it is ever needed +# again in the future ... + +# def hermitian_fixed_points(self): +# dimensions = len(self.shape) +# mid_index = np.array(self.shape)//2 +# ndlist = [1]*dimensions +# for k in range(dimensions): +# if self.shape[k] % 2 == 0: +# ndlist[k] = 2 +# ndlist = tuple(ndlist) +# fixed_points = [] +# for index in np.ndindex(ndlist): +# for k in range(dimensions): +# if self.shape[k] % 2 != 0 and self.zerocenter[k]: +# index = list(index) +# index[k] = 1 +# index = tuple(index) +# fixed_points += [tuple(index * mid_index)] +# return fixed_points def hermitianize_inverter(self, x, axes): # calculate the number of dimensions the input array has diff --git a/nifty/spaces/space/space.py b/nifty/spaces/space/space.py index 1cd59e5c22afbee5bac2b19023c70d9612ff04b6..99ecee1e068d7cff89ec266461583f6e80742aa6 100644 --- a/nifty/spaces/space/space.py +++ b/nifty/spaces/space/space.py @@ -161,19 +161,6 @@ class Space(DomainObject): raise NotImplementedError( "There is no generic co-smoothing kernel for Space base class.") - def hermitian_fixed_points(self): - """ Returns the array points which remain invariant under the action - of `hermitianize_inverter` - - - Returns - ------- - list of index-tuples - The list contains the index-coordinates of the invariant points. - - """ - return None - def hermitianize_inverter(self, x, axes): """ Inverts/flips x in the context of Hermitian decomposition. diff --git a/test/test_field.py b/test/test_field.py index c0730910eb89b59561af3ebe4771604de1dbd0d2..ab192818acfb37fb36598b8f3569702c13982f23 100644 --- a/test/test_field.py +++ b/test/test_field.py @@ -67,6 +67,8 @@ class Test_Functionality(unittest.TestCase): r2 = RGSpace(s2, harmonic=True, zerocenter=(z2,)) ra = RGSpace(s1+s2, harmonic=True, zerocenter=(z1, z2)) + if preserve: + complexdata=True v = np.random.random(s1+s2) if complexdata: v = v + 1j*np.random.random(s1+s2) diff --git a/test/test_spaces/test_lm_space.py b/test/test_spaces/test_lm_space.py index 0d84a52fcad22e85f2d9f602a1968862a9654255..4820ba7ace725a3b6d1ed62cdbacb3835682d8f1 100644 --- a/test/test_spaces/test_lm_space.py +++ b/test/test_spaces/test_lm_space.py @@ -127,7 +127,3 @@ class LMSpaceFunctionalityTests(unittest.TestCase): def test_distance_array(self, lmax, expected): l = LMSpace(lmax) assert_almost_equal(l.get_distance_array('not').data, expected) - - def test_hermitian_fixed_points(self): - x = LMSpace(5) - assert_equal(x.hermitian_fixed_points(), None) diff --git a/test/test_spaces/test_rg_space.py b/test/test_spaces/test_rg_space.py index 901afa27c2f365ef75e6007765ad172cd937a285..c3faada1e2f385b5ac3c9fc99759f3597ccedc1c 100644 --- a/test/test_spaces/test_rg_space.py +++ b/test/test_spaces/test_rg_space.py @@ -190,8 +190,3 @@ class RGSpaceFunctionalityTests(unittest.TestCase): assert_almost_equal(res, expected) if inplace: assert_(x is res) - - def test_hermitian_fixed_points(self): - x = RGSpace((5, 6, 5, 6), zerocenter=[False, False, True, True]) - assert_equal(x.hermitian_fixed_points(), - [(0, 0, 2, 0), (0, 0, 2, 3), (0, 3, 2, 0), (0, 3, 2, 3)])