Commit 31932e59 by Philipp Arras

Merge remote-tracking branch 'origin/NIFTy_6' into integration_operator

parents 83a7a4fc 4d8c1460
Pipeline #75200 passed with stages
in 8 minutes and 23 seconds
 Changes since NIFTy 5: Minimum Python version increased to 3.6 ======================================= New operators ============= In addition to the below changes, the following operators were introduced: * UniformOperator: Transforms a Gaussian into a uniform distribution * VariableCovarianceGaussianEnergy: Energy operator for inferring covariances * MultiLinearEinsum: Multi-linear version of numpy's einsum with derivates * LinearEinsum: Linear version of numpy's einsum with one free field * PartialConjugate: Conjugates parts of a multi-field * SliceOperator: Geometry preserving mask operator * SplitOperator: Splits a single field into a multi-field FFT convention adjusted ======================= ... ...
 ... ... @@ -45,7 +45,7 @@ Installation ### Requirements - [Python 3](https://www.python.org/) (3.5.x or later) - [Python 3](https://www.python.org/) (3.6.x or later) - [SciPy](https://www.scipy.org/) Optional dependencies: ... ...
 ... ... @@ -25,6 +25,7 @@ from .operators.adder import Adder from .operators.diagonal_operator import DiagonalOperator from .operators.distributors import DOFDistributor, PowerDistributor from .operators.domain_tuple_field_inserter import DomainTupleFieldInserter from .operators.einsum import LinearEinsum, MultiLinearEinsum from .operators.contraction_operator import ContractionOperator, IntegrationOperator from .operators.linear_interpolation import LinearInterpolator from .operators.endomorphic_operator import EndomorphicOperator ... ... @@ -38,12 +39,13 @@ from .operators.regridding_operator import RegriddingOperator from .operators.sampling_enabler import SamplingEnabler, SamplingDtypeSetter from .operators.sandwich_operator import SandwichOperator from .operators.scaling_operator import ScalingOperator from .operators.selection_operators import SliceOperator, SplitOperator from .operators.block_diagonal_operator import BlockDiagonalOperator from .operators.outer_product_operator import OuterProduct from .operators.simple_linear_operators import ( VdotOperator, ConjugationOperator, Realizer, FieldAdapter, ducktape, GeometryRemover, NullOperator, MatrixProductOperator, PartialExtractor, SwitchSpacesOperator) VdotOperator, ConjugationOperator, Realizer, FieldAdapter, ducktape, GeometryRemover, NullOperator, PartialExtractor) from .operators.matrix_product_operator import MatrixProductOperator from .operators.value_inserter import ValueInserter from .operators.energy_operators import ( EnergyOperator, GaussianEnergy, PoissonianEnergy, InverseGammaLikelihood, ... ...
 ... ... @@ -61,7 +61,7 @@ def _lognormal_moments(mean, sig, N=0): if not np.all(sig > 0): raise ValueError("sig must be greater 0; got {!r}".format(sig)) logsig = np.sqrt(np.log((sig/mean)**2 + 1)) logsig = np.sqrt(np.log1p((sig/mean)**2)) logmean = np.log(mean) - logsig**2/2 return logmean, logsig ... ...
 ... ... @@ -22,18 +22,27 @@ from .utilities import frozendict, indent class MultiDomain(object): """A tuple of domains corresponding to a direct sum. This class is the domain of the direct sum of fields defined on (possibly different) domains. To make an instance of this class, call `MultiDomain.make(inp)`. This class is the domain of the direct sum of fields defined on (possibly different) domains. To make an instance of this class, call `MultiDomain.make(inp)`. Notes ----- For consistency and to be independent of the order of insertion, the keys within a multi-domain are sorted. Hence, renaming a domain may result in it being placed at a different index within a multi-domain. This is especially important if a sequence of, e.g., random numbers is distributed sequentially over a multi-domain. In this example, ordering keys differently will change the resulting :class:`MultiField`. """ _domainCache = {} def __init__(self, dict, _callingfrommake=False): def __init__(self, dct, _callingfrommake=False): if not _callingfrommake: raise NotImplementedError( 'To create a MultiDomain call `MultiDomain.make()`.') self._keys = tuple(sorted(dict.keys())) self._domains = tuple(dict[key] for key in self._keys) self._keys = tuple(sorted(dct.keys())) self._domains = tuple(dct[key] for key in self._keys) self._idx = frozendict({key: i for i, key in enumerate(self._keys)}) @staticmethod ... ...
 ... ... @@ -102,6 +102,29 @@ class MultiField(Operator): @staticmethod def from_random(random_type, domain, dtype=np.float64, **kwargs): """Draws a random multi-field with the given parameters. Parameters ---------- random_type : 'pm1', 'normal', or 'uniform' The random distribution to use. domain : DomainTuple The domain of the output random Field. dtype : type The datatype of the output random Field. Returns ------- MultiField The newly created :class:`MultiField`. Notes ----- The individual fields within this multi-field will be drawn in alphabetical order of the multi-field's domain keys. As a consequence, renaming these keys may cause the multi-field to be filled with different random numbers, even for the same initial RNG state. """ domain = MultiDomain.make(domain) if isinstance(dtype, dict): dtype = {kk: np.dtype(dt) for kk, dt in dtype.items()} ... ...