Commit d985e8ee authored by Theo Steininger's avatar Theo Steininger

Fixed power for power_synthesize on LMSpace.

Added first methods for __repr__
parent dd80d59d
Pipeline #13043 failed with stages
in 5 minutes and 16 seconds
......@@ -45,6 +45,10 @@ class DomainObject(Versionable, Loggable, object):
# _global_id is used in the Versioning module from keepers
self._ignore_for_hash = ['_global_id']
@abc.abstractmethod
def __repr__(self):
raise NotImplementedError
def __hash__(self):
# Extract the identifying parts from the vars(self) dict.
result_hash = 0
......
......@@ -386,6 +386,7 @@ class Field(Loggable, Versionable, object):
for part in [hermitian_part, anti_hermitian_part]]
power_spectrum = hermitian_power + 1j * anti_hermitian_power
else:
power_spectrum = self._calculate_power_spectrum(
x=self.val,
......@@ -396,11 +397,7 @@ class Field(Loggable, Versionable, object):
# create the result field and put power_spectrum into it
result_domain = list(self.domain)
result_domain[space_index] = power_domain
if decompose_power:
result_dtype = np.complex
else:
result_dtype = np.float
result_dtype = power_spectrum.dtype
result_field = self.copy_empty(
domain=result_domain,
......@@ -586,32 +583,43 @@ class Field(Loggable, Versionable, object):
# hermitianize for the first space
(h, a) = domain[spaces[0]].hermitian_decomposition(
val,
domain_axes[spaces[0]])
domain_axes[spaces[0]],
preserve_gaussian_variance=True)
# hermitianize all remaining spaces using the iterative formula
for space in xrange(1, len(spaces)):
(hh, ha) = \
domain[space].hermitian_decomposition(h, domain_axes[space])
(ah, aa) = \
domain[space].hermitian_decomposition(a, domain_axes[space])
(hh, ha) = domain[space].hermitian_decomposition(
h,
domain_axes[space],
preserve_gaussian_variance=True)
(ah, aa) = domain[space].hermitian_decomposition(
a,
domain_axes[space],
preserve_gaussian_variance=True)
c = (hh - ha - ah + aa).conjugate()
h = (val + c)/2.
a = (val - c)/2.
# correct variance
fixed_points = [domain[i].hermitian_fixed_points() for i in spaces]
# check if there was at least one flipping during hermitianization
flipped_Q = np.any([fp is not None for fp in fixed_points])
# if the array got flipped, correct the variance
if flipped_Q:
h *= np.sqrt(2)
a *= np.sqrt(2)
# in principle one must not correct the variance for the fixed
# points of the hermitianization. However, for a complex field
# the input field looses half of its power at its fixed points
# 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]
# # check if there was at least one flipping during hermitianization
# flipped_Q = np.any([fp is not None for fp in fixed_points])
# # if the array got flipped, correct the variance
# if flipped_Q:
# h *= np.sqrt(2)
# a *= np.sqrt(2)
#
# 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),
......
......@@ -100,6 +100,9 @@ class GLSpace(Space):
# ---Mandatory properties and methods---
def __repr__(self):
return ("GLSpace(nlat=%r, nlon=%r)" % (self.nlat, self.nlon))
@property
def harmonic(self):
return False
......
......@@ -84,6 +84,9 @@ class HPSpace(Space):
# ---Mandatory properties and methods---
def __repr__(self):
return ("HPSpace(nside=%r)" % self.nside)
@property
def harmonic(self):
return False
......
......@@ -91,10 +91,19 @@ class LMSpace(Space):
def hermitian_decomposition(self, x, axes=None,
preserve_gaussian_variance=False):
if issubclass(x.dtype.type, np.complexfloating):
hermitian_part = x.copy_empty()
anti_hermitian_part = x.copy_empty()
hermitian_part[:] = x.real
anti_hermitian_part[:] = x.imag * 1j
if preserve_gaussian_variance:
hermitian_part *= np.sqrt(2)
anti_hermitian_part *= np.sqrt(2)
else:
hermitian_part = x.copy()
anti_hermitian_part = x.copy_empty()
anti_hermitian_part.val[:] = 0
return (hermitian_part, anti_hermitian_part)
# def hermitian_fixed_points(self):
......@@ -102,6 +111,9 @@ class LMSpace(Space):
# ---Mandatory properties and methods---
def __repr__(self):
return ("LMSpace(lmax=%r)" % self.lmax)
@property
def harmonic(self):
return True
......
......@@ -149,6 +149,13 @@ class PowerSpace(Space):
# ---Mandatory properties and methods---
def __repr__(self):
return ("PowerSpace(harmonic_partner=%r, distribution_strategy=%r, "
"logarithmic=%r, nbin=%r, binbounds=%r)"
% (self.harmonic_partner, self.pindex.distribution_strategy,
self.config['logarithmic'], self.config['nbin'],
self.config['binbounds']))
@property
def harmonic(self):
return True
......
......@@ -52,7 +52,7 @@ class RGSpace(Space):
----------
shape : {int, numpy.ndarray}
Number of grid points or numbers of gridpoints along each axis.
zerocenter : {bool, numpy.ndarray}, *optional*
zerocenter : {bool, numpy.ndarray} *optional*
Whether x==0 (or k==0, respectively) is located in the center of
the grid (or the center of each axis speparately) or not.
(default: False).
......@@ -120,24 +120,16 @@ class RGSpace(Space):
return (hermitian_part, anti_hermitian_part)
# def hermitian_fixed_points(self):
# shape = self.shape
# mid_index = np.array(shape)//2
# ndlist = [2 if (shape[i] % 2 == 0) else 1 for i in xrange(len(shape))]
# ndlist = tuple(ndlist)
# odd_axes_list = np.array([1 if (shape[i] % 2 == 1) else 0
# for i in xrange(len(shape))])
# fixed_points = []
# for i in np.ndindex(ndlist):
# fixed_points += [tuple((i+odd_axes_list) * mid_index)]
# return fixed_points
def _hermitianize_correct_variance(self, hermitian_part,
anti_hermitian_part, axes):
# Correct the variance by multiplying sqrt(2)
hermitian_part = hermitian_part * np.sqrt(2)
anti_hermitian_part = anti_hermitian_part * np.sqrt(2)
# If the dtype of the input is complex, the fixed points lose the power
# of their imaginary-part (or real-part, respectively). Therefore
# the factor of sqrt(2) also applies there
if not issubclass(hermitian_part.dtype.type, np.complexfloating):
# The fixed points of the point inversion must not be averaged.
# Hence one must divide out the sqrt(2) again
# -> Get the middle index of the array
......@@ -193,6 +185,10 @@ class RGSpace(Space):
# ---Mandatory properties and methods---
def __repr__(self):
return ("RGSpace(shape=%r, zerocenter=%r, distances=%r, harmonic=%r)"
% (self.shape, self.zerocenter, self.distances, self.harmonic))
@property
def harmonic(self):
return self._harmonic
......
......@@ -64,12 +64,6 @@ class Space(DomainObject):
@abc.abstractproperty
def harmonic(self):
""" Returns True if this space is a harmonic space.
Raises
------
NotImplementedError
If called for this abstract class.
"""
raise NotImplementedError
......@@ -83,12 +77,8 @@ class Space(DomainObject):
float
A real number representing the sum of all pixel volumes.
Raises
------
NotImplementedError
If called for this abstract class.
"""
raise NotImplementedError(
"There is no generic volume for the Space base class.")
......@@ -122,11 +112,6 @@ class Space(DomainObject):
distributed_data_object
A d2o containing the distances
Raises
------
NotImplementedError
If called for this abstract class.
"""
raise NotImplementedError(
......@@ -157,11 +142,6 @@ class Space(DomainObject):
A smoothing operation that multiplies values with a Gaussian
kernel.
Raises
------
NotImplementedError :
If called for this abstract class.
"""
raise NotImplementedError(
......@@ -184,7 +164,11 @@ class Space(DomainObject):
Specifies the axes of x which correspond to this space.
preserve_gaussian_variance : bool *optional*
FIXME: figure out what this does
If the hermitian decomposition is done via computing the half
sums and differences of `x` and mirrored `x`, all points except the
fixed points lose half of their variance. If `x` is complex also
the lose half of their variance since the real(/imaginary) part
gets lost.
Returns
-------
......@@ -192,14 +176,6 @@ class Space(DomainObject):
A tuple of two distributed_data_objects, the first being the
hermitian and the second the anti-hermitian part of x.
Raises
------
NotImplementedError
If called for this abstract class.
"""
raise NotImplementedError
def __repr__(self):
return str(type(self)) + "\n"
......@@ -18,14 +18,15 @@
import unittest
import numpy as np
from numpy.testing import assert_, assert_equal
from itertools import product
from types import LambdaType
from numpy.testing import assert_, assert_raises, assert_equal
from nifty import LMSpace, GLSpace, HPSpace
from nifty.config import dependency_injector as di
from test.common import expand, generate_spaces, generate_harmonic_spaces
from d2o import distributed_data_object
from nifty.spaces import *
class SpaceInterfaceTests(unittest.TestCase):
@expand(product(generate_spaces(), [
......@@ -34,28 +35,17 @@ class SpaceInterfaceTests(unittest.TestCase):
['dim', int],
['total_volume', np.float]]))
def test_property_ret_type(self, space, attr_expected_type):
assert_(
isinstance(getattr(
space,
attr_expected_type[0]
), attr_expected_type[1])
)
assert_(isinstance(getattr(space, attr_expected_type[0]),
attr_expected_type[1]))
@expand(product(generate_harmonic_spaces(), [
['get_fft_smoothing_kernel_function', None, LambdaType],
['get_distance_array', 'not', distributed_data_object],
['get_fft_smoothing_kernel_function', 2.0, LambdaType],
]))
def test_method_ret_type(self, space, method_expected_type):
getattr(
space, method_expected_type[0])(*method_expected_type[1:-1])
assert_equal(
type(getattr(
space,
method_expected_type[0])(*method_expected_type[1:-1])
),
method_expected_type[-1]
)
assert_(type(getattr(space, method_expected_type[0])(
*method_expected_type[1:-1])) is
method_expected_type[-1])
@expand([[space] for space in generate_spaces()])
def test_copy(self, space):
......@@ -63,3 +53,7 @@ class SpaceInterfaceTests(unittest.TestCase):
assert_(space is not space.copy())
# make sure contents are the same
assert_equal(space, space.copy())
@expand([[space] for space in generate_spaces()])
def test_repr(self, space):
assert_(space == eval(space.__repr__()))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment