diff --git a/demos/polynomial_fit.py b/demos/polynomial_fit.py index 969e6822ad9d30de7d59037d6ae6166e8bcef83e..020c030c4bf550f32ba4f7a7b4d1b98d75bfa568 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 151c45f6249a5070a8c3b5d9f65af8aa9f967d4a..5d42ad197aef49612f9689103cb179f5d882cc17 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 fd7c5ed5f9c909fab6f883186e7765431f1a90e2..a807595dbc3732c133b8b5660ed5ac57c533ee42 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 fff20b0dcc33f87ee413efef05598ca169e1a550..529dea48d1823f2d405dca041b0356dd5962637b 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 9df48287c4809458639f49feb3013420d5e15da9..a8a99b9546996ba32cd26bc8ffb4293e65c21430 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 54a046849c60415916f049a6fd032d541941a13f..d40d0c1029ce5166b05526d7f628b8b616b278f0 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 3f0d7abee08dd1b3dd2026caa99074a930d22b6c..6f3833ec952a39151b1faa33e55adda468113a44 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 75a905c4fd9c7c2f6c4a2125c52bbb5cdb1d04f4..1cd6d9523a835417377e1c6902091ca483e04f14 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 3375117518c3b1561cc6cc9820241020a7570dc1..14b9c9a10f1ce692ce86ae09a8245e68b2894ddb 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 5c5c6d34d3e32e09d4f72342bfb6373a871ed24d..489b7777337a87c7d368ebacaf5074968818a009 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 f8c112f230520032c2990c83ff0df16e7d115f5d..2dd414f1db943e0d583b49e78117adef29206ff6 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 3ddfefd0dbfad08e6b268106de9ee4b64c506851..963159f189d2c72465c338134dd7e82e611b0fe7 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 d14df4af4c065bb8ecd939cb3d067ae780f6c84d..c213a6e8f71396e3a508e8abb778b5649a275db4 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 c7d98be961ea5adc4e10343b71e375017b13ae7a..6c6a49c245273bb0dca73c7bd87dd8d3a17597dc 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 f6fd528d2da8e514d29915719e762a5ed083ad08..b7fbe1393d51179b3ac9228c703fbc19d1e8b31e 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 9fad98daa7e056ff7a286398c0c939c72a8b2c6f..057355b0dfeabadf0625671eddb82d33be3590be 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 9a601e15c6bdd965b50a4fcdf2127996ffbdba39..eaa0b4a7ad0ddd281c0a64f3e00fe366045bad8f 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 1f48c8d83a6d2f7a4646146f0e2b4449e0fdb723..499b09f794e8bd3788e001155527a265d049182b 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 548ba0474e26f88e1e1dda3cbf3086e18c722454..16365a7b3919482b65c1c037fea5bb97079d6d4a 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 506964163c3d44da2f0005c4f4eae9e9af3338cc..5864ae038acead4c04fbd381dcf802ba685bd1cf 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 ef864760cbb34b9bbcde2d3ec2851f1902e30546..4f7538317122fd6599579da967161c5339ecb432 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 08939a45fc079396dc47ddea569bb63a4662557f..6044e6e32161f1eb24fefddd8aa4cf5d20d1d15e 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 dc5c75e94bd04bd7b334f0edb91a073d5f99f673..a355989919275b0f63ad18bbd768a47e0cfd87bc 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 db12ba311ba508687bbf3fb5cb125b9753ae9289..9d7d04b5cb28205b7499f09ef8827ded77be4733 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 b0f67daa4f1888ccf4be7a9ec9a3a210986dba53..afe53e03f6dc3fa6c040b0b7abbd9de11de9f7d1 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 e07d3da107e7d8bf4a06bf241dd326fb4be9dc6c..480540848da3eb06ee8fd0dfd8ed976705c71ba9 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 9b7cc7654a871e12f40dfa5eed61dcf72b914a73..1be154473f6997d03a23f889d6cff4bbc70c24d2 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 a779b9279f3ee8ad44e4c72c35eabdba56324cd3..21a63e743f2b4bc58ccb695c9c630385e3638b4c 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 a74b4292eba9ea0df18561de0d1f651adc17a1f0..4cca76fa39e5994e5d5d1be194acdecd4b35a72a 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 6cc700f2f56eede76da405c927b5b7dbbc77b8af..abd9ed1115383a6fee8f47cf3f9f913e7b802569 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 6d4d79c38a519b04cd8571575a4fe927e77cdc5e..338f087c1ab6568fab2310ee990df42993012e30 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 b2d0f07b374e4e81988b9b65f1baaba548fff011..2bd7919d70c627ec548683f594cb20767f1bf708 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 fb4d6117d6d59f0f3083bf0ba0917bd2f3530591..53530e2c593d580e2340364d62ba02ea1a1b0602 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 728f4ad864044a97bb8a2d4a7fb1805d68d21ca3..66933b2cb2a9cae8e9bc747d1fac367a5f79a219 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 76ea55a504b87a67c9390564736277ced014dfbb..6895bd7a62507870d6747004f01ece73b2cc2d90 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 b3d5e5d426b491d9a6ef76ded38b2c471f5e7bbd..3f8c5ff4e9b41ae32151b764d81972fa140dc70f 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 cb047d3247b7c204b705ef36088dfb3903be2337..f5b5573db49f82a850a5629f247b5e12673a494b 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 618b022c875d128df7dd1b0787cc6f20afadb576..06d33e4adf382549c9ef689d1dc8b903193e90da 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 de43f1650b9cef0ce002346d17ac6a8f0576f92f..0dcf73d7bcef809ea984826d0a39e3b587a77c04 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 5c4d6276a64454a958978a48b6adc30837cc490b..b8f5370eed61199b093027e3baedb55acf2e8ee6 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 057d45ad1826968f9b2b915291f7cbcad3546a17..35be855cae96a36c8aa168787dd3016fd412a6f9 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()