From 12c44bb48b0ddd7c70a1c81f4ae5d16f9bb0d424 Mon Sep 17 00:00:00 2001 From: Martin Reinecke <martin@mpa-garching.mpg.de> Date: Wed, 8 Aug 2018 20:43:26 +0200 Subject: [PATCH] ... and more cleanups --- demos/polynomial_fit.py | 6 +-- nifty5/domains/dof_space.py | 1 - nifty5/domains/domain.py | 8 ++-- nifty5/domains/gl_space.py | 2 - nifty5/domains/hp_space.py | 1 - nifty5/domains/lm_space.py | 1 - nifty5/domains/log_rg_space.py | 2 - nifty5/domains/power_space.py | 2 - nifty5/domains/rg_space.py | 2 - nifty5/domains/unstructured_domain.py | 1 - nifty5/library/los_response.py | 7 +--- nifty5/minimization/descent_minimizer.py | 1 - nifty5/minimization/energy.py | 1 - .../minimization/gradient_norm_controller.py | 1 - nifty5/minimization/line_energy.py | 1 - nifty5/minimization/scipy_minimizer.py | 2 - nifty5/operators/block_diagonal_operator.py | 9 +---- nifty5/operators/central_zero_padder.py | 7 +--- nifty5/operators/chain_operator.py | 5 --- nifty5/operators/diagonal_operator.py | 7 +--- nifty5/operators/dof_distributor.py | 7 +--- nifty5/operators/domain_distributor.py | 5 +-- nifty5/operators/energy_operators.py | 5 --- nifty5/operators/exp_transform.py | 5 +-- nifty5/operators/field_zero_padder.py | 6 +-- nifty5/operators/harmonic_operators.py | 28 ++----------- nifty5/operators/inversion_enabler.py | 6 +-- nifty5/operators/laplace_operator.py | 6 +-- nifty5/operators/linear_operator.py | 2 +- nifty5/operators/mask_operator.py | 5 +-- nifty5/operators/operator_adapter.py | 6 +-- nifty5/operators/qht_operator.py | 5 +-- nifty5/operators/relaxed_sum_operator.py | 5 --- nifty5/operators/sampling_enabler.py | 6 +-- nifty5/operators/sandwich_operator.py | 6 +-- nifty5/operators/scaling_operator.py | 6 +-- nifty5/operators/simple_linear_operators.py | 40 ++++--------------- nifty5/operators/slope_operator.py | 5 +-- nifty5/operators/sum_operator.py | 5 --- nifty5/operators/symmetrizing_operator.py | 5 +-- test/test_minimization/test_minimizers.py | 5 +-- 41 files changed, 36 insertions(+), 200 deletions(-) diff --git a/demos/polynomial_fit.py b/demos/polynomial_fit.py index 969e6822a..020c030c4 100644 --- a/demos/polynomial_fit.py +++ b/demos/polynomial_fit.py @@ -38,13 +38,13 @@ class PolynomialResponse(ift.LinearOperator): """ def __init__(self, domain, sampling_points): - super(PolynomialResponse, self).__init__() if not (isinstance(domain, ift.UnstructuredDomain) and isinstance(x, np.ndarray)): raise TypeError self._domain = ift.DomainTuple.make(domain) tgt = ift.UnstructuredDomain(sampling_points.shape) self._target = ift.DomainTuple.make(tgt) + self._capability = self.TIMES | self.ADJOINT_TIMES sh = (self.target.size, domain.size) self._mat = np.empty(sh) @@ -62,10 +62,6 @@ class PolynomialResponse(ift.LinearOperator): out = self._mat.conj().T.dot(val) return ift.from_global_data(self._tgt(mode), out) - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - # Generate some mock data N_params = 10 diff --git a/nifty5/domains/dof_space.py b/nifty5/domains/dof_space.py index 151c45f62..5d42ad197 100644 --- a/nifty5/domains/dof_space.py +++ b/nifty5/domains/dof_space.py @@ -40,7 +40,6 @@ class DOFSpace(StructuredDomain): _needed_for_hash = ["_dvol"] def __init__(self, dof_weights): - super(DOFSpace, self).__init__() self._dvol = tuple(dof_weights) @property diff --git a/nifty5/domains/domain.py b/nifty5/domains/domain.py index fd7c5ed5f..a807595db 100644 --- a/nifty5/domains/domain.py +++ b/nifty5/domains/domain.py @@ -25,10 +25,6 @@ from ..utilities import NiftyMetaBase class Domain(NiftyMetaBase()): """The abstract class repesenting a (structured or unstructured) domain. """ - - def __init__(self): - self._hash = None - def __repr__(self): raise NotImplementedError @@ -40,7 +36,9 @@ class Domain(NiftyMetaBase()): Only members that are explicitly added to :attr:`._needed_for_hash` will be used for hashing. """ - if self._hash is None: + try: + return self._hash + except AttributeError: h = 0 for key in self._needed_for_hash: h ^= hash(vars(self)[key]) diff --git a/nifty5/domains/gl_space.py b/nifty5/domains/gl_space.py index fff20b0dc..529dea48d 100644 --- a/nifty5/domains/gl_space.py +++ b/nifty5/domains/gl_space.py @@ -43,8 +43,6 @@ class GLSpace(StructuredDomain): _needed_for_hash = ["_nlat", "_nlon"] def __init__(self, nlat, nlon=None): - super(GLSpace, self).__init__() - self._nlat = int(nlat) if self._nlat < 1: raise ValueError("nlat must be a positive number.") diff --git a/nifty5/domains/hp_space.py b/nifty5/domains/hp_space.py index 9df48287c..a8a99b954 100644 --- a/nifty5/domains/hp_space.py +++ b/nifty5/domains/hp_space.py @@ -40,7 +40,6 @@ class HPSpace(StructuredDomain): _needed_for_hash = ["_nside"] def __init__(self, nside): - super(HPSpace, self).__init__() self._nside = int(nside) if self._nside < 1: raise ValueError("nside must be >=1.") diff --git a/nifty5/domains/lm_space.py b/nifty5/domains/lm_space.py index 54a046849..d40d0c102 100644 --- a/nifty5/domains/lm_space.py +++ b/nifty5/domains/lm_space.py @@ -48,7 +48,6 @@ class LMSpace(StructuredDomain): _needed_for_hash = ["_lmax", "_mmax"] def __init__(self, lmax, mmax=None): - super(LMSpace, self).__init__() self._lmax = np.int(lmax) if self._lmax < 0: raise ValueError("lmax must be >=0.") diff --git a/nifty5/domains/log_rg_space.py b/nifty5/domains/log_rg_space.py index 3f0d7abee..6f3833ec9 100644 --- a/nifty5/domains/log_rg_space.py +++ b/nifty5/domains/log_rg_space.py @@ -32,8 +32,6 @@ class LogRGSpace(StructuredDomain): _needed_for_hash = ['_shape', '_bindistances', '_t_0', '_harmonic'] def __init__(self, shape, bindistances, t_0, harmonic=False): - super(LogRGSpace, self).__init__() - self._harmonic = bool(harmonic) if np.isscalar(shape): diff --git a/nifty5/domains/power_space.py b/nifty5/domains/power_space.py index 75a905c4f..1cd6d9523 100644 --- a/nifty5/domains/power_space.py +++ b/nifty5/domains/power_space.py @@ -158,8 +158,6 @@ class PowerSpace(StructuredDomain): return PowerSpace.linear_binbounds(nbin, lbound, rbound) def __init__(self, harmonic_partner, binbounds=None): - super(PowerSpace, self).__init__() - if not (isinstance(harmonic_partner, StructuredDomain) and harmonic_partner.harmonic): raise ValueError("harmonic_partner must be a harmonic space.") diff --git a/nifty5/domains/rg_space.py b/nifty5/domains/rg_space.py index 337511751..14b9c9a10 100644 --- a/nifty5/domains/rg_space.py +++ b/nifty5/domains/rg_space.py @@ -51,8 +51,6 @@ class RGSpace(StructuredDomain): _needed_for_hash = ["_distances", "_shape", "_harmonic"] def __init__(self, shape, distances=None, harmonic=False): - super(RGSpace, self).__init__() - self._harmonic = bool(harmonic) if np.isscalar(shape): shape = (shape,) diff --git a/nifty5/domains/unstructured_domain.py b/nifty5/domains/unstructured_domain.py index 5c5c6d34d..489b77773 100644 --- a/nifty5/domains/unstructured_domain.py +++ b/nifty5/domains/unstructured_domain.py @@ -38,7 +38,6 @@ class UnstructuredDomain(Domain): _needed_for_hash = ["_shape"] def __init__(self, shape): - super(UnstructuredDomain, self).__init__() try: self._shape = tuple([int(i) for i in shape]) except TypeError: diff --git a/nifty5/library/los_response.py b/nifty5/library/los_response.py index f8c112f23..2dd414f1d 100644 --- a/nifty5/library/los_response.py +++ b/nifty5/library/los_response.py @@ -134,9 +134,8 @@ class LOSResponse(LinearOperator): """ def __init__(self, domain, starts, ends, sigmas_low=None, sigmas_up=None): - - super(LOSResponse, self).__init__() self._domain = DomainTuple.make(domain) + self._capability = self.TIMES | self.ADJOINT_TIMES if ((not isinstance(self.domain[0], RGSpace)) or (len(self._domain) != 1)): @@ -221,10 +220,6 @@ class LOSResponse(LinearOperator): self._target = DomainTuple.make(UnstructuredDomain(nlos)) - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - def apply(self, x, mode): self._check_input(x, mode) if mode == self.TIMES: diff --git a/nifty5/minimization/descent_minimizer.py b/nifty5/minimization/descent_minimizer.py index 3ddfefd0d..963159f18 100644 --- a/nifty5/minimization/descent_minimizer.py +++ b/nifty5/minimization/descent_minimizer.py @@ -42,7 +42,6 @@ class DescentMinimizer(Minimizer): """ def __init__(self, controller, line_searcher=LineSearchStrongWolfe()): - super(DescentMinimizer, self).__init__() self._controller = controller self.line_searcher = line_searcher diff --git a/nifty5/minimization/energy.py b/nifty5/minimization/energy.py index d14df4af4..c213a6e8f 100644 --- a/nifty5/minimization/energy.py +++ b/nifty5/minimization/energy.py @@ -47,7 +47,6 @@ class Energy(NiftyMetaBase()): """ def __init__(self, position): - super(Energy, self).__init__() self._position = position self._gradnorm = None diff --git a/nifty5/minimization/gradient_norm_controller.py b/nifty5/minimization/gradient_norm_controller.py index c7d98be96..6c6a49c24 100644 --- a/nifty5/minimization/gradient_norm_controller.py +++ b/nifty5/minimization/gradient_norm_controller.py @@ -47,7 +47,6 @@ class GradientNormController(IterationController): def __init__(self, tol_abs_gradnorm=None, tol_rel_gradnorm=None, convergence_level=1, iteration_limit=None, name=None): - super(GradientNormController, self).__init__() self._tol_abs_gradnorm = tol_abs_gradnorm self._tol_rel_gradnorm = tol_rel_gradnorm self._convergence_level = convergence_level diff --git a/nifty5/minimization/line_energy.py b/nifty5/minimization/line_energy.py index f6fd528d2..b7fbe1393 100644 --- a/nifty5/minimization/line_energy.py +++ b/nifty5/minimization/line_energy.py @@ -50,7 +50,6 @@ class LineEnergy(object): """ def __init__(self, line_position, energy, line_direction, offset=0.): - super(LineEnergy, self).__init__() self._line_position = float(line_position) self._line_direction = line_direction diff --git a/nifty5/minimization/scipy_minimizer.py b/nifty5/minimization/scipy_minimizer.py index 9fad98daa..057355b0d 100644 --- a/nifty5/minimization/scipy_minimizer.py +++ b/nifty5/minimization/scipy_minimizer.py @@ -74,7 +74,6 @@ class ScipyMinimizer(Minimizer): """ def __init__(self, method, options, need_hessp, bounds): - super(ScipyMinimizer, self).__init__() if not dobj.is_numpy(): raise NotImplementedError self._method = method @@ -130,7 +129,6 @@ def L_BFGS_B(ftol, gtol, maxiter, maxcor=10, disp=False, bounds=None): class ScipyCG(Minimizer): def __init__(self, tol, maxiter): - super(ScipyCG, self).__init__() if not dobj.is_numpy(): raise NotImplementedError self._tol = tol diff --git a/nifty5/operators/block_diagonal_operator.py b/nifty5/operators/block_diagonal_operator.py index 9a601e15c..eaa0b4a7a 100644 --- a/nifty5/operators/block_diagonal_operator.py +++ b/nifty5/operators/block_diagonal_operator.py @@ -33,21 +33,16 @@ class BlockDiagonalOperator(EndomorphicOperator): dictionary with operators domain names as keys and LinearOperators as items """ - super(BlockDiagonalOperator, self).__init__() if not isinstance(domain, MultiDomain): raise TypeError("MultiDomain expected") if not isinstance(operators, tuple): raise TypeError("tuple expected") self._domain = domain self._ops = operators - self._cap = self._all_ops + self._capability = self._all_ops for op in self._ops: if op is not None: - self._cap &= op.capability - - @property - def capability(self): - return self._cap + self._capability &= op.capability def apply(self, x, mode): self._check_input(x, mode) diff --git a/nifty5/operators/central_zero_padder.py b/nifty5/operators/central_zero_padder.py index 1f48c8d83..499b09f79 100644 --- a/nifty5/operators/central_zero_padder.py +++ b/nifty5/operators/central_zero_padder.py @@ -16,8 +16,6 @@ from .. import dobj # highest frequency. class CentralZeroPadder(LinearOperator): def __init__(self, domain, new_shape, space=0): - super(CentralZeroPadder, self).__init__() - self._domain = DomainTuple.make(domain) self._space = utilities.infer_space(self._domain, space) dom = self._domain[self._space] @@ -35,6 +33,7 @@ class CentralZeroPadder(LinearOperator): self._target = list(self._domain) self._target[self._space] = tgt self._target = DomainTuple.make(self._target) + self._capability = self.TIMES | self.ADJOINT_TIMES slicer = [] axes = self._target.axes[self._space] @@ -53,10 +52,6 @@ class CentralZeroPadder(LinearOperator): self.slicer[i] = tuple(tmp) self.slicer = tuple(self.slicer) - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - def apply(self, x, mode): self._check_input(x, mode) x = x.val diff --git a/nifty5/operators/chain_operator.py b/nifty5/operators/chain_operator.py index 548ba0474..16365a7b3 100644 --- a/nifty5/operators/chain_operator.py +++ b/nifty5/operators/chain_operator.py @@ -31,7 +31,6 @@ class ChainOperator(LinearOperator): def __init__(self, ops, _callingfrommake=False): if not _callingfrommake: raise NotImplementedError - super(ChainOperator, self).__init__() self._ops = ops self._capability = self._all_ops for op in ops: @@ -132,10 +131,6 @@ class ChainOperator(LinearOperator): return self.make([op._flip_modes(trafo) for op in self._ops]) raise ValueError("invalid operator transformation") - @property - def capability(self): - return self._capability - def apply(self, x, mode): self._check_mode(mode) t_ops = self._ops if mode & self._backwards else reversed(self._ops) diff --git a/nifty5/operators/diagonal_operator.py b/nifty5/operators/diagonal_operator.py index 506964163..5864ae038 100644 --- a/nifty5/operators/diagonal_operator.py +++ b/nifty5/operators/diagonal_operator.py @@ -57,8 +57,6 @@ class DiagonalOperator(EndomorphicOperator): """ def __init__(self, diagonal, domain=None, spaces=None): - super(DiagonalOperator, self).__init__() - if not isinstance(diagonal, Field): raise TypeError("Field object required") if domain is None: @@ -99,6 +97,7 @@ class DiagonalOperator(EndomorphicOperator): def _fill_rest(self): self._ldiag.flags.writeable = False self._complex = utilities.iscomplextype(self._ldiag.dtype) + self._capability = self._all_ops if not self._complex: lmin = self._ldiag.min() if self._ldiag.size > 0 else 1. self._diagmin = dobj.np_allreduce_min(np.array(lmin))[()] @@ -150,10 +149,6 @@ class DiagonalOperator(EndomorphicOperator): return Field.from_local_data(x.domain, x.local_data*xdiag) return Field.from_local_data(x.domain, x.local_data/xdiag) - @property - def capability(self): - return self._all_ops - def _flip_modes(self, trafo): xdiag = self._ldiag if self._complex and (trafo & self.ADJOINT_BIT): diff --git a/nifty5/operators/dof_distributor.py b/nifty5/operators/dof_distributor.py index ef864760c..4f7538317 100644 --- a/nifty5/operators/dof_distributor.py +++ b/nifty5/operators/dof_distributor.py @@ -54,8 +54,6 @@ class DOFDistributor(LinearOperator): """ def __init__(self, dofdex, target=None, space=None): - super(DOFDistributor, self).__init__() - if target is None: target = dofdex.domain self._target = DomainTuple.make(target) @@ -98,6 +96,7 @@ class DOFDistributor(LinearOperator): dom = list(self._target) dom[self._space] = other_space self._domain = DomainTuple.make(dom) + self._capability = self.TIMES | self.ADJOINT_TIMES if dobj.default_distaxis() in self._domain.axes[self._space]: dofdex = dobj.local_data(dofdex) @@ -142,7 +141,3 @@ class DOFDistributor(LinearOperator): def apply(self, x, mode): self._check_input(x, mode) return self._times(x) if mode == self.TIMES else self._adjoint_times(x) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/domain_distributor.py b/nifty5/operators/domain_distributor.py index 08939a45f..6044e6e32 100644 --- a/nifty5/operators/domain_distributor.py +++ b/nifty5/operators/domain_distributor.py @@ -35,6 +35,7 @@ class DomainDistributor(LinearOperator): self._domain = [tgt for i, tgt in enumerate(self._target) if i in self._spaces] self._domain = DomainTuple.make(self._domain) + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -49,7 +50,3 @@ class DomainDistributor(LinearOperator): else: return x.sum([s for s in range(len(x.domain)) if s not in self._spaces]) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/energy_operators.py b/nifty5/operators/energy_operators.py index dc5c75e94..a35598991 100644 --- a/nifty5/operators/energy_operators.py +++ b/nifty5/operators/energy_operators.py @@ -36,7 +36,6 @@ class EnergyOperator(Operator): class SquaredNormOperator(EnergyOperator): def __init__(self, domain): - super(SquaredNormOperator, self).__init__() self._domain = domain def apply(self, x): @@ -50,7 +49,6 @@ class SquaredNormOperator(EnergyOperator): class QuadraticFormOperator(EnergyOperator): def __init__(self, op): from .endomorphic_operator import EndomorphicOperator - super(QuadraticFormOperator, self).__init__() if not isinstance(op, EndomorphicOperator): raise TypeError("op must be an EndomorphicOperator") self._op = op @@ -67,7 +65,6 @@ class QuadraticFormOperator(EnergyOperator): class GaussianEnergy(EnergyOperator): def __init__(self, mean=None, covariance=None, domain=None): - super(GaussianEnergy, self).__init__() self._domain = None if mean is not None: self._checkEquivalence(mean.domain) @@ -132,7 +129,6 @@ class BernoulliEnergy(EnergyOperator): class Hamiltonian(EnergyOperator): def __init__(self, lh, ic_samp=None): - super(Hamiltonian, self).__init__() self._lh = lh self._prior = GaussianEnergy(domain=lh.domain) self._ic_samp = ic_samp @@ -156,7 +152,6 @@ class SampledKullbachLeiblerDivergence(EnergyOperator): h: Hamiltonian N: Number of samples to be used """ - super(SampledKullbachLeiblerDivergence, self).__init__() self._h = h self._domain = h.domain self._res_samples = tuple(res_samples) diff --git a/nifty5/operators/exp_transform.py b/nifty5/operators/exp_transform.py index db12ba311..9d7d04b5c 100644 --- a/nifty5/operators/exp_transform.py +++ b/nifty5/operators/exp_transform.py @@ -33,6 +33,7 @@ from ..utilities import infer_space, special_add_at class ExpTransform(LinearOperator): def __init__(self, target, dof, space=0): self._target = DomainTuple.make(target) + self._capability = self.TIMES | self.ADJOINT_TIMES self._space = infer_space(self._target, space) tgt = self._target[self._space] if not ((isinstance(tgt, RGSpace) and tgt.harmonic) or @@ -115,7 +116,3 @@ class ExpTransform(LinearOperator): if d == ax: x = dobj.redistribute(x, dist=ax) return Field(self._tgt(mode), val=x) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/field_zero_padder.py b/nifty5/operators/field_zero_padder.py index b0f67daa4..afe53e03f 100644 --- a/nifty5/operators/field_zero_padder.py +++ b/nifty5/operators/field_zero_padder.py @@ -13,7 +13,6 @@ from .. import utilities class FieldZeroPadder(LinearOperator): def __init__(self, domain, new_shape, space=0): - super(FieldZeroPadder, self).__init__() self._domain = DomainTuple.make(domain) self._space = utilities.infer_space(self._domain, space) dom = self._domain[self._space] @@ -30,10 +29,7 @@ class FieldZeroPadder(LinearOperator): self._target = list(self._domain) self._target[self._space] = tgt self._target = DomainTuple.make(self._target) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) diff --git a/nifty5/operators/harmonic_operators.py b/nifty5/operators/harmonic_operators.py index e07d3da10..480540848 100644 --- a/nifty5/operators/harmonic_operators.py +++ b/nifty5/operators/harmonic_operators.py @@ -57,10 +57,9 @@ class FFTOperator(LinearOperator): """ def __init__(self, domain, target=None, space=None): - super(FFTOperator, self).__init__() - # Initialize domain and target self._domain = DomainTuple.make(domain) + self._capability = self._all_ops self._space = utilities.infer_space(self._domain, space) adom = self._domain[self._space] @@ -127,10 +126,6 @@ class FFTOperator(LinearOperator): fct *= self._target[self._space].scalar_dvol return Tval if fct == 1 else Tval*fct - @property - def capability(self): - return self._all_ops - class HartleyOperator(LinearOperator): """Transforms between a pair of position and harmonic RGSpaces. @@ -162,10 +157,9 @@ class HartleyOperator(LinearOperator): """ def __init__(self, domain, target=None, space=None): - super(HartleyOperator, self).__init__() - # Initialize domain and target self._domain = DomainTuple.make(domain) + self._capability = self._all_ops self._space = utilities.infer_space(self._domain, space) adom = self._domain[self._space] @@ -239,10 +233,6 @@ class HartleyOperator(LinearOperator): fct = self._target[self._space].scalar_dvol return Tval if fct == 1 else Tval*fct - @property - def capability(self): - return self._all_ops - class SHTOperator(LinearOperator): """Transforms between a harmonic domain on the sphere and a position @@ -272,10 +262,9 @@ class SHTOperator(LinearOperator): """ def __init__(self, domain, target=None, space=None): - super(SHTOperator, self).__init__() - # Initialize domain and target self._domain = DomainTuple.make(domain) + self._capability = self.TIMES | self.ADJOINT_TIMES self._space = utilities.infer_space(self._domain, space) hspc = self._domain[self._space] @@ -351,10 +340,6 @@ class SHTOperator(LinearOperator): odat = dobj.redistribute(odat, dist=dobj.distaxis(x.val)) return Field(tdom, odat) - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - class HarmonicTransformOperator(LinearOperator): """Transforms between a harmonic domain and a position domain counterpart. @@ -384,8 +369,6 @@ class HarmonicTransformOperator(LinearOperator): """ def __init__(self, domain, target=None, space=None): - super(HarmonicTransformOperator, self).__init__() - domain = DomainTuple.make(domain) space = utilities.infer_space(domain, space) @@ -399,15 +382,12 @@ class HarmonicTransformOperator(LinearOperator): self._op = SHTOperator(domain, target, space) self._domain = self._op.domain self._target = self._op.target + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) return self._op.apply(x, mode) - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - def HarmonicSmoothingOperator(domain, sigma, space=None): """ This function returns an operator that carries out a smoothing with diff --git a/nifty5/operators/inversion_enabler.py b/nifty5/operators/inversion_enabler.py index 9b7cc7654..1be154473 100644 --- a/nifty5/operators/inversion_enabler.py +++ b/nifty5/operators/inversion_enabler.py @@ -51,15 +51,11 @@ class InversionEnabler(EndomorphicOperator): """ def __init__(self, op, iteration_controller, approximation=None): - super(InversionEnabler, self).__init__() self._op = op self._ic = iteration_controller self._approximation = approximation self._domain = op.domain - - @property - def capability(self): - return self._addInverse[self._op.capability] + self._capability = self._addInverse[self._op.capability] def apply(self, x, mode): self._check_mode(mode) diff --git a/nifty5/operators/laplace_operator.py b/nifty5/operators/laplace_operator.py index a779b9279..21a63e743 100644 --- a/nifty5/operators/laplace_operator.py +++ b/nifty5/operators/laplace_operator.py @@ -47,8 +47,8 @@ class LaplaceOperator(EndomorphicOperator): """ def __init__(self, domain, space=None, logarithmic=True): - super(LaplaceOperator, self).__init__() self._domain = DomainTuple.make(domain) + self._capability = self.TIMES | self.ADJOINT_TIMES self._space = infer_space(self._domain, space) if not isinstance(self._domain[self._space], PowerSpace): @@ -68,10 +68,6 @@ class LaplaceOperator(EndomorphicOperator): self._dposc[1:] += self._dpos self._dposc *= 0.5 - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES - def _times(self, x): axes = x.domain.axes[self._space] axis = axes[0] diff --git a/nifty5/operators/linear_operator.py b/nifty5/operators/linear_operator.py index a74b4292e..4cca76fa3 100644 --- a/nifty5/operators/linear_operator.py +++ b/nifty5/operators/linear_operator.py @@ -145,7 +145,7 @@ class LinearOperator(Operator): :attr:`INVERSE_TIMES`, and :attr:`ADJOINT_INVERSE_TIMES`, joined together by the "|" operator. """ - raise NotImplementedError + return self._capability def apply(self, x, mode): """ Applies the Operator to a given `x`, in a specified `mode`. diff --git a/nifty5/operators/mask_operator.py b/nifty5/operators/mask_operator.py index 6cc700f2f..abd9ed111 100644 --- a/nifty5/operators/mask_operator.py +++ b/nifty5/operators/mask_operator.py @@ -38,6 +38,7 @@ class MaskOperator(LinearOperator): self._domain = DomainTuple.make(mask.domain) self._mask = np.logical_not(mask.to_global_data()) self._target = DomainTuple.make(UnstructuredDomain(self._mask.sum())) + self._capability = self.TIMES | self.ADJOINT_TIMES def data_indices(self): if len(self.domain.shape) == 1: @@ -55,7 +56,3 @@ class MaskOperator(LinearOperator): res[self._mask] = x res[~self._mask] = 0 return Field.from_global_data(self.domain, res) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/operator_adapter.py b/nifty5/operators/operator_adapter.py index 6d4d79c38..338f087c1 100644 --- a/nifty5/operators/operator_adapter.py +++ b/nifty5/operators/operator_adapter.py @@ -45,17 +45,13 @@ class OperatorAdapter(LinearOperator): """ def __init__(self, op, op_transform): - super(OperatorAdapter, self).__init__() self._op = op self._trafo = int(op_transform) if self._trafo < 1 or self._trafo > 3: raise ValueError("invalid operator transformation") self._domain = self._op._dom(1 << self._trafo) self._target = self._op._tgt(1 << self._trafo) - - @property - def capability(self): - return self._capTable[self._trafo][self._op.capability] + self._capability = self._capTable[self._trafo][self._op.capability] def _flip_modes(self, trafo): newtrafo = trafo ^ self._trafo diff --git a/nifty5/operators/qht_operator.py b/nifty5/operators/qht_operator.py index b2d0f07b3..2bd7919d7 100644 --- a/nifty5/operators/qht_operator.py +++ b/nifty5/operators/qht_operator.py @@ -59,6 +59,7 @@ class QHTOperator(LinearOperator): self._domain[self._space] = \ self._target[self._space].get_default_codomain() self._domain = DomainTuple.make(self._domain) + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -76,7 +77,3 @@ class QHTOperator(LinearOperator): if i == ax: x = dobj.redistribute(x, dist=ax) return Field(self._tgt(mode), val=x) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/relaxed_sum_operator.py b/nifty5/operators/relaxed_sum_operator.py index fb4d6117d..53530e2c5 100644 --- a/nifty5/operators/relaxed_sum_operator.py +++ b/nifty5/operators/relaxed_sum_operator.py @@ -32,7 +32,6 @@ class RelaxedSumOperator(LinearOperator): """Class representing sums of operators with compatible domains.""" def __init__(self, ops): - super(RelaxedSumOperator, self).__init__() self._ops = ops self._domain = domain_union([op.domain for op in ops]) self._target = domain_union([op.target for op in ops]) @@ -50,10 +49,6 @@ class RelaxedSumOperator(LinearOperator): def adjoint(self): return RelaxedSumOperator([op.adjoint for op in self._ops]) - @property - def capability(self): - return self._capability - def apply(self, x, mode): self._check_input(x, mode) res = None diff --git a/nifty5/operators/sampling_enabler.py b/nifty5/operators/sampling_enabler.py index 728f4ad86..66933b2cb 100644 --- a/nifty5/operators/sampling_enabler.py +++ b/nifty5/operators/sampling_enabler.py @@ -50,13 +50,13 @@ class SamplingEnabler(EndomorphicOperator): def __init__(self, likelihood, prior, iteration_controller, approximation=None): - super(SamplingEnabler, self).__init__() self._op = likelihood + prior self._likelihood = likelihood self._prior = prior self._ic = iteration_controller self._approximation = approximation self._domain = self._op.domain + self._capability = self._op.capability def draw_sample(self, from_inverse=False, dtype=np.float64): try: @@ -77,9 +77,5 @@ class SamplingEnabler(EndomorphicOperator): energy, convergence = inverter(energy) return energy.position - @property - def capability(self): - return self._op.capability - def apply(self, x, mode): return self._op.apply(x, mode) diff --git a/nifty5/operators/sandwich_operator.py b/nifty5/operators/sandwich_operator.py index 76ea55a50..6895bd7a6 100644 --- a/nifty5/operators/sandwich_operator.py +++ b/nifty5/operators/sandwich_operator.py @@ -34,11 +34,11 @@ class SandwichOperator(EndomorphicOperator): def __init__(self, bun, cheese, op, _callingfrommake=False): if not _callingfrommake: raise NotImplementedError - super(SandwichOperator, self).__init__() self._bun = bun self._cheese = cheese self._op = op self._domain = op.domain + self._capability = op._capability @staticmethod def make(bun, cheese=None): @@ -66,10 +66,6 @@ class SandwichOperator(EndomorphicOperator): return op return SandwichOperator(bun, cheese, op, _callingfrommake=True) - @property - def capability(self): - return self._op.capability - def apply(self, x, mode): return self._op.apply(x, mode) diff --git a/nifty5/operators/scaling_operator.py b/nifty5/operators/scaling_operator.py index b3d5e5d42..3f8c5ff4e 100644 --- a/nifty5/operators/scaling_operator.py +++ b/nifty5/operators/scaling_operator.py @@ -54,12 +54,12 @@ class ScalingOperator(EndomorphicOperator): def __init__(self, factor, domain): from ..sugar import makeDomain - super(ScalingOperator, self).__init__() if not np.isscalar(factor): raise TypeError("Scalar required") self._factor = factor self._domain = makeDomain(domain) + self._capability = self._all_ops def apply(self, x, mode): self._check_input(x, mode) @@ -82,10 +82,6 @@ class ScalingOperator(EndomorphicOperator): fct = 1./fct return ScalingOperator(fct, self._domain) - @property - def capability(self): - return self._all_ops - def draw_sample(self, from_inverse=False, dtype=np.float64): fct = self._factor if fct.imag != 0. or fct.real < 0.: diff --git a/nifty5/operators/simple_linear_operators.py b/nifty5/operators/simple_linear_operators.py index cb047d324..f5b5573db 100644 --- a/nifty5/operators/simple_linear_operators.py +++ b/nifty5/operators/simple_linear_operators.py @@ -33,14 +33,10 @@ from ..multi_field import MultiField class VdotOperator(LinearOperator): def __init__(self, field): - super(VdotOperator, self).__init__() self._field = field self._domain = field.domain self._target = DomainTuple.scalar_domain() - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -51,13 +47,9 @@ class VdotOperator(LinearOperator): class SumReductionOperator(LinearOperator): def __init__(self, domain): - super(SumReductionOperator, self).__init__() self._domain = domain self._target = DomainTuple.scalar_domain() - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -68,12 +60,8 @@ class SumReductionOperator(LinearOperator): class ConjugationOperator(EndomorphicOperator): def __init__(self, domain): - super(ConjugationOperator, self).__init__() self._domain = domain - - @property - def capability(self): - return self._all_ops + self._capability = self._all_ops def apply(self, x, mode): self._check_input(x, mode) @@ -82,12 +70,8 @@ class ConjugationOperator(EndomorphicOperator): class Realizer(EndomorphicOperator): def __init__(self, domain): - super(Realizer, self).__init__() self._domain = domain - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -99,10 +83,7 @@ class FieldAdapter(LinearOperator): self._domain = MultiDomain.make(dom) self._name = name_dom self._target = dom[name_dom] - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -131,14 +112,10 @@ class GeometryRemover(LinearOperator): """ def __init__(self, domain): - super(GeometryRemover, self).__init__() self._domain = DomainTuple.make(domain) target_list = [UnstructuredDomain(dom.shape) for dom in self._domain] self._target = DomainTuple.make(target_list) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES + self._capability = self.TIMES | self.ADJOINT_TIMES def apply(self, x, mode): self._check_input(x, mode) @@ -162,6 +139,7 @@ class NullOperator(LinearOperator): from ..sugar import makeDomain self._domain = makeDomain(domain) self._target = makeDomain(target) + self._capability = self.TIMES | self.ADJOINT_TIMES @staticmethod def _nullfield(dom): @@ -176,7 +154,3 @@ class NullOperator(LinearOperator): if mode == self.TIMES: return self._nullfield(self._target) return self._nullfield(self._domain) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/slope_operator.py b/nifty5/operators/slope_operator.py index 618b022c8..06d33e4ad 100644 --- a/nifty5/operators/slope_operator.py +++ b/nifty5/operators/slope_operator.py @@ -37,6 +37,7 @@ class SlopeOperator(LinearOperator): self._domain = DomainTuple.make(domain) self._target = DomainTuple.make(target) + self._capability = self.TIMES | self.ADJOINT_TIMES if self.domain[0].shape != (len(self.target[0].shape) + 1,): raise AssertionError("Shape mismatch!") @@ -74,7 +75,3 @@ class SlopeOperator(LinearOperator): for i in range(self.ndim): res[i] = np.sum(self.pos[i] * xglob) * self._sigmas[i] return Field.from_global_data(self.domain, res) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/nifty5/operators/sum_operator.py b/nifty5/operators/sum_operator.py index de43f1650..0dcf73d7b 100644 --- a/nifty5/operators/sum_operator.py +++ b/nifty5/operators/sum_operator.py @@ -31,7 +31,6 @@ class SumOperator(LinearOperator): def __init__(self, ops, neg, dom, tgt, _callingfrommake=False): if not _callingfrommake: raise NotImplementedError - super(SumOperator, self).__init__() self._ops = ops self._neg = neg self._domain = dom @@ -163,10 +162,6 @@ class SumOperator(LinearOperator): def adjoint(self): return self.make([op.adjoint for op in self._ops], self._neg) - @property - def capability(self): - return self._capability - def apply(self, x, mode): self._check_mode(mode) res = None diff --git a/nifty5/operators/symmetrizing_operator.py b/nifty5/operators/symmetrizing_operator.py index 5c4d6276a..b8f5370ee 100644 --- a/nifty5/operators/symmetrizing_operator.py +++ b/nifty5/operators/symmetrizing_operator.py @@ -30,6 +30,7 @@ from .. import utilities class SymmetrizingOperator(EndomorphicOperator): def __init__(self, domain, space=0): self._domain = DomainTuple.make(domain) + self._capability = self.TIMES | self.ADJOINT_TIMES self._space = utilities.infer_space(self._domain, space) dom = self._domain[self._space] if not (isinstance(dom, LogRGSpace) and not dom.harmonic): @@ -48,7 +49,3 @@ class SymmetrizingOperator(EndomorphicOperator): if i == ax: tmp = dobj.redistribute(tmp, dist=ax) return Field(self.target, val=tmp) - - @property - def capability(self): - return self.TIMES | self.ADJOINT_TIMES diff --git a/test/test_minimization/test_minimizers.py b/test/test_minimization/test_minimizers.py index 057d45ad1..35be855ca 100644 --- a/test/test_minimization/test_minimizers.py +++ b/test/test_minimization/test_minimizers.py @@ -99,15 +99,12 @@ class Test_Minimizers(unittest.TestCase): class RBCurv(ift.EndomorphicOperator): def __init__(self, loc): self._loc = loc.to_global_data_rw() + self._capability = self.TIMES @property def domain(self): return space - @property - def capability(self): - return self.TIMES - def apply(self, x, mode): self._check_input(x, mode) inp = x.to_global_data_rw() -- GitLab