Commit 6733e2dc authored by theos's avatar theos
Browse files

Merge branch 'feature/field_multiple_space' of gitlab.mpcdf.mpg.de:ift/NIFTy...

Merge branch 'feature/field_multiple_space' of gitlab.mpcdf.mpg.de:ift/NIFTy into feature/field_multiple_space
parents be57ac4e 3e9e7803
......@@ -1203,8 +1203,6 @@ class point_space(space):
dot : scalar
Inner product of the two arrays.
"""
x = self.cast(x)
y = self.cast(y)
result = x.vdot(y)
......
......@@ -215,10 +215,9 @@ class field(object):
if kwargs == {}:
val = self.cast(0)
else:
val = map(lambda z: self.get_random_values(domain=self.domain,
codomain=z,
**kwargs),
self.codomain)
val = self.get_random_values(domain=self.domain,
codomain=self.codomain,
**kwargs)
self.set_val(new_val=val, copy=copy)
def _get_dtype_from_domain(self, domain=None):
......@@ -291,30 +290,15 @@ class field(object):
self.codomain = codomain
return codomain
def get_random_values(self, **kwargs):
def get_random_values(self, domain=None, codomain=None, **kwargs):
raise NotImplementedError(about._errors.cstring(
"ERROR: no generic instance method 'enforce_power'."))
def __len__(self):
return int(self.get_dim()[0])
def apply_scalar_function(self, function, inplace=False):
if inplace:
working_field = self
else:
working_field = self.copy_empty()
data_object = map(
lambda z: self.domain.apply_scalar_function(z, function, inplace),
self.get_val())
working_field.set_val(data_object)
return working_field
def copy(self, domain=None, codomain=None):
copied_val = map(
lambda z: self.domain.unary_operation(z, op='copy'),
self.get_val())
def copy(self, domain=None, codomain=None, **kwargs):
copied_val = self._unary_operation(self.get_val(), op='copy', **kwargs)
new_field = self.copy_empty(domain=domain, codomain=codomain)
new_field.set_val(new_val=copied_val)
return new_field
......@@ -370,9 +354,7 @@ class field(object):
"""
if new_val is not None:
if copy:
new_val = map(
lambda z: self.unary_operation(z, 'copy'),
new_val)
new_val = self.unary_operation(new_val, op='copy')
self.val = self.cast(new_val)
return self.val
......@@ -425,9 +407,6 @@ class field(object):
else:
return dim
def _map(self, function, *args):
return utilities.field_map(self.get_shape(), function, *args)
def cast(self, x=None, dtype=None):
if dtype is not None:
dtype = np.dtype(dtype)
......@@ -572,7 +551,7 @@ class field(object):
self.codomain = new_codomain
return self.codomain
def weight(self, power=1, overwrite=False):
def weight(self, new_val=None, power=1, overwrite=False, spaces=None):
"""
Returns the field values, weighted with the volume factors to a
given power. The field values will optionally be overwritten.
......@@ -598,8 +577,15 @@ class field(object):
else:
new_field = self.copy_empty()
new_val = map(lambda y: self.domain.calc_weight(y, power=power),
self.get_val())
if new_val is None:
new_val = self.get_val()
if spaces is None:
spaces = range(len(self.get_shape()))
for ind in spaces:
new_val = self.domain[ind].calc_weigth(new_val, power=power,
axis=self._axis_list[
ind])
new_field.set_val(new_val=new_val)
return new_field
......@@ -663,22 +649,18 @@ class field(object):
# Case 3: x is something else
else:
# Cast the input in order to cure dtype and shape differences
casted_x = self._cast_to_ishape(x)
# Compute the dot respecting the fact of discrete/continous spaces
if self.domain.discrete or bare:
result = map(
lambda z1, z2: self.domain.calc_dot(z1, z2),
self.get_val(),
casted_x)
else:
result = map(
lambda z1, z2: self.domain.calc_dot(
self.domain.calc_weight(z1, power=1),
z2),
self.get_val(), casted_x)
self.field_type_dot("dummy call, reverse spaces iteration")
casted_x = self.cast(x)
# Compute the dot respecting the fact of discrete/continous spaces
if not (np.isreal(self.get_val()) or bare):
casted_x = self.weight(casted_x, power=1)
result = self.get_val().dot(casted_x)
return np.sum(result, axis=axis)
def field_type_dot(self,something):
pass
def vdot(self, *args, **kwargs):
return self.dot(*args, **kwargs)
......@@ -735,15 +717,17 @@ class field(object):
else:
work_field = self.copy_empty()
new_val = map(
lambda z: self.domain.unary_operation(z, 'conjugate'),
self.get_val())
new_val = self.get_val()
for ind, space in self.domain:
new_val = space.unary_operation(new_val, op='conjugate',
axis=self._axis_list[ind])
work_field.set_val(new_val=new_val)
return work_field
def transform(self, new_domain=None, new_codomain=None, overwrite=False,
**kwargs):
spaces=None, **kwargs):
"""
Computes the transform of the field using the appropriate conjugate
transformation.
......@@ -780,11 +764,15 @@ class field(object):
else:
assert (new_domain.check_codomain(new_codomain))
new_val = map(
lambda z: self.domain.calc_transform(
z, codomain=new_domain, **kwargs),
self.get_val())
new_val = self.get_val()
if spaces is None:
spaces = range(len(self.get_shape()))
else:
for ind in spaces:
new_val = self.domain[ind].calc_transform(new_val,
codomain=new_domain,
axis=self._axis_list[
ind], **kwargs)
if overwrite:
return_field = self
return_field.set_codomain(new_codomain=new_codomain, force=True)
......@@ -826,9 +814,10 @@ class field(object):
else:
new_field = self.copy_empty()
new_val = map(
lambda z: self.domain.calc_smooth(z, sigma=sigma, **kwargs),
self.get_val())
new_val = self.get_val()
for ind, space in self.domain:
new_val = space.calc_smooth(new_val, sigma=sigma,
axis=self._axis_list[ind], **kwargs)
new_field.set_val(new_val=new_val)
return new_field
......@@ -876,10 +865,12 @@ class field(object):
kwargs.__delitem__("codomain")
about.warnings.cprint("WARNING: codomain was removed from kwargs.")
power_spectrum = map(
lambda z: self.domain.calc_power(z, codomain=self.codomain,
**kwargs),
self.get_val())
power_spectrum = self.get_val()
for ind, space in self.domain:
power_spectrum = space.calc_smooth(power_spectrum,
codomain=self.codomain,
axis=self._axis_list[ind],
**kwargs)
return power_spectrum
......@@ -909,8 +900,7 @@ class field(object):
The new diagonal operator instance.
"""
any_zero_Q = map(lambda z: (z == 0).any(), self.get_val())
any_zero_Q = np.any(any_zero_Q)
any_zero_Q = np.any(map(lambda z: (z == 0), self.get_val()))
if any_zero_Q:
raise AttributeError(
about._errors.cstring("ERROR: singular operator."))
......
......@@ -746,7 +746,7 @@ class rg_space(point_space):
return sample
def calc_weight(self, x, power=1):
def calc_weight(self, x, axes=None, power=1):
"""
Weights a given array with the pixel volumes to a given power.
......@@ -756,6 +756,8 @@ class rg_space(point_space):
Array to be weighted.
power : float, *optional*
Power of the pixel volumes to be used (default: 1).
axes : None, tuple
Ignored in this case since it's a scalar operation.
Returns
-------
......@@ -812,7 +814,7 @@ class rg_space(point_space):
codomain : nifty.rg_space, *optional*
codomain space to which the transformation shall map
(default: None).
axes : None or tuple
axes : None, tuple
Axes in the array which should be transformed.
Returns
......@@ -844,7 +846,7 @@ class rg_space(point_space):
return Tx
def calc_smooth(self, x, sigma=0, codomain=None):
def calc_smooth(self, x, sigma=0, codomain=None, axes=None):
"""
Smoothes an array of field values by convolution with a Gaussian
kernel.
......@@ -857,6 +859,8 @@ class rg_space(point_space):
Standard deviation of the Gaussian kernel, specified in units
of length in position space; for testing: a sigma of -1 will be
reset to a reasonable value (default: 0).
axes: None, tuple
Axes which should be smoothed
Returns
-------
......@@ -883,21 +887,20 @@ class rg_space(point_space):
else:
codomain = self.get_codomain()
x = self.calc_transform(x, codomain=codomain)
x = codomain._calc_smooth_helper(x, sigma)
x = codomain.calc_transform(x, codomain=self)
x = self.calc_transform(x, codomain=codomain, axes=axes)
x = codomain._calc_smooth_helper(x, sigma, axes=axes)
x = codomain.calc_transform(x, codomain=self, axes=axes)
return x
def _calc_smooth_helper(self, x, sigma):
def _calc_smooth_helper(self, x, sigma, axes=None):
# multiply the gaussian kernel, etc...
# Cast the input
x = self.cast(x)
if axes is None:
axes = range(len(x.shape))
# if x is hermitian it remains hermitian during smoothing
# TODO look at this later
# if self.datamodel in RG_DISTRIBUTION_STRATEGIES:
remeber_hermitianQ = x.hermitian
remember_hermitianQ = x.hermitian
# Define the Gaussian kernel function
gaussian = lambda x: np.exp(-2. * np.pi**2 * x**2 * sigma**2)
......@@ -916,15 +919,15 @@ class rg_space(point_space):
# compute the actual kernel vector
gaussian_kernel_vector = gaussian(k)
# blow up the vector to an array of shape (1,.,1,len(nk),1,.,1)
blown_up_shape = [1, ] * len(nx)
blown_up_shape[i] = len(gaussian_kernel_vector)
blown_up_shape = [1, ] * len(x.shape)
blown_up_shape[axes[i]] = len(gaussian_kernel_vector)
gaussian_kernel_vector =\
gaussian_kernel_vector.reshape(blown_up_shape)
# apply the blown-up gaussian_kernel_vector
x = x*gaussian_kernel_vector
try:
x.hermitian = remeber_hermitianQ
x.hermitian = remember_hermitianQ
except AttributeError:
pass
......
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