Commit bf947d1b authored by Martin Reinecke's avatar Martin Reinecke

Merge branch 'cf_wo_asperity' into 'NIFTy_7'

Allow for opting out of asperity and flexibility

See merge request !556
parents 2e872c5d 9dc11964
Pipeline #77882 passed with stages
in 26 minutes and 6 seconds
Changes since NIFTy 6
=====================
CorrelatedFieldMaker interface change
-------------------------------------
The interface of `ift.CorrelatedFieldMaker.make` and
`ift.CorrelatedFieldMaker.add_fluctuations` changed; it now expects the mean
and the standard deviation of their various parameters not as separate
arguments but as a tuple.
Furthermore, it is now possible to disable the asperity and the flexibility
together with the asperity in the correlated field model. Note that disabling
only the flexibility is not possible.
SimpleCorrelatedField
---------------------
A simplified version of the correlated field model was introduced which does not
allow for multiple power spectra, the presence of a degree of freedom parameter
`dofdex`, or `total_N` larger than zero. Except for the above mentioned
limitations, it is equivalent to `ift.CorrelatedFieldMaker`. Hence, if one
wants to understand the implementation idea behind the model, it is easier to
grasp from reading `ift.SimpleCorrelatedField` than from going through
`ift.CorrelatedFieldMaker`.
Change in external dependencies
-------------------------------
......@@ -20,7 +43,7 @@ The implementation tests for nonlinear operators are now available in
MetricGaussianKL interface
--------------------------
Users do not instanciate `MetricGaussianKL` by its constructor anymore. Rather
Users do not instantiate `MetricGaussianKL` by its constructor anymore. Rather
`MetricGaussianKL.make()` shall be used.
......@@ -91,10 +114,10 @@ New approach for sampling complex numbers
When calling draw_sample_with_dtype with a complex dtype,
the variance is now used for the imaginary part and real part separately.
This is done in order to be consistent with the Hamiltonian.
Note that by this,
Note that by this,
```
np.std(ift.from_random(domain, 'normal', dtype=np.complex128).val)
````
````
does not give 1, but sqrt(2) as a result.
......
......@@ -73,10 +73,10 @@ def main():
sp2 = ift.RGSpace(npix2)
# Set up signal model
cfmaker = ift.CorrelatedFieldMaker.make(0., 1e-2, 1e-6, '')
cfmaker.add_fluctuations(sp1, 0.1, 1e-2, 1, .1, .01, .5, -2, 1., 'amp1')
cfmaker.add_fluctuations(sp2, 0.1, 1e-2, 1, .1, .01, .5,
-1.5, .5, 'amp2')
cfmaker = ift.CorrelatedFieldMaker.make(0., (1e-2, 1e-6), '')
cfmaker.add_fluctuations(sp1, (0.1, 1e-2), (1, .1), (.01, .5), (-2, 1.), 'amp1')
cfmaker.add_fluctuations(sp2, (0.1, 1e-2), (1, .1), (.01, .5),
(-1.5, .5), 'amp2')
correlated_field = cfmaker.finalize()
A1 = cfmaker.normalized_amplitudes[0]
......
......@@ -92,7 +92,7 @@ from .library.correlated_fields_simple import SimpleCorrelatedField
from . import extra
from .utilities import memo, frozendict
from .utilities import memo, frozendict, myassert
from .logger import logger
......
......@@ -18,7 +18,6 @@
from itertools import combinations
import numpy as np
from numpy.testing import assert_
from .domain_tuple import DomainTuple
from .field import Field
......@@ -29,6 +28,7 @@ from .operators.energy_operators import EnergyOperator
from .operators.linear_operator import LinearOperator
from .operators.operator import Operator
from .sugar import from_random
from .utilities import myassert
__all__ = ["check_linear_operator", "check_operator",
"assert_allclose"]
......@@ -137,20 +137,6 @@ def assert_equal(f1, f2):
assert_equal(val, f2[key])
def _nozero(fld):
if isinstance(fld, Field):
return np.testing.assert_((fld != 0).s_all())
for val in fld.values():
_nozero(val)
def _allzero(fld):
if isinstance(fld, Field):
return np.testing.assert_((fld == 0.).s_all())
for val in fld.values():
_allzero(val)
def _adjoint_implementation(op, domain_dtype, target_dtype, atol, rtol,
only_r_linear):
needed_cap = op.TIMES | op.ADJOINT_TIMES
......@@ -206,32 +192,32 @@ def _domain_check_linear(op, domain_dtype=None, inp=None):
inp = from_random(op.domain, "normal", dtype=domain_dtype)
elif inp is None:
raise ValueError('Need to specify either dtype or inp')
assert_(inp.domain is op.domain)
assert_(op(inp).domain is op.target)
myassert(inp.domain is op.domain)
myassert(op(inp).domain is op.target)
def _domain_check_nonlinear(op, loc):
_domain_check(op)
assert_(isinstance(loc, (Field, MultiField)))
assert_(loc.domain is op.domain)
myassert(isinstance(loc, (Field, MultiField)))
myassert(loc.domain is op.domain)
for wm in [False, True]:
lin = Linearization.make_var(loc, wm)
reslin = op(lin)
assert_(lin.domain is op.domain)
assert_(lin.target is op.domain)
assert_(lin.val.domain is lin.domain)
assert_(reslin.domain is op.domain)
assert_(reslin.target is op.target)
assert_(reslin.val.domain is reslin.target)
assert_(reslin.target is op.target)
assert_(reslin.jac.domain is reslin.domain)
assert_(reslin.jac.target is reslin.target)
assert_(lin.want_metric == reslin.want_metric)
myassert(lin.domain is op.domain)
myassert(lin.target is op.domain)
myassert(lin.val.domain is lin.domain)
myassert(reslin.domain is op.domain)
myassert(reslin.target is op.target)
myassert(reslin.val.domain is reslin.target)
myassert(reslin.target is op.target)
myassert(reslin.jac.domain is reslin.domain)
myassert(reslin.jac.target is reslin.target)
myassert(lin.want_metric == reslin.want_metric)
_domain_check_linear(reslin.jac, inp=loc)
_domain_check_linear(reslin.jac.adjoint, inp=reslin.jac(loc))
if reslin.metric is not None:
assert_(reslin.metric.domain is reslin.metric.target)
assert_(reslin.metric.domain is op.domain)
myassert(reslin.metric.domain is reslin.metric.target)
myassert(reslin.metric.domain is op.domain)
def _domain_check(op):
......
This diff is collapsed.
......@@ -78,7 +78,7 @@ class SimpleCorrelatedField(Operator):
xi = ducktape(dom, None, prefix + 'spectrum')
shift = np.ones(dom.shape)
shift[0] = _log_vol(pspace)**2/12.
shift[0] = _log_vol(pspace)**2 / 12.
shift = makeField(dom, shift)
if asperity is None:
asp = makeOp(shift.ptw("sqrt")) @ (xi*sig_flex)
......
......@@ -405,3 +405,10 @@ def lognormal_moments(mean, sigma, N=0):
logsigma = np.sqrt(np.log1p((sigma / mean)**2))
logmean = np.log(mean) - logsigma**2 / 2
return logmean, logsigma
def myassert(val):
"""Safe alternative to python's assert statement which is active even if
`__debug__` is False."""
if not val:
raise AssertionError
......@@ -17,9 +17,10 @@
import numpy as np
import pytest
from numpy.testing import assert_, assert_allclose, assert_raises
from numpy.testing import assert_allclose, assert_raises
import nifty7 as ift
from nifty7 import myassert
from .common import setup_function, teardown_function
......@@ -55,13 +56,13 @@ def test_kl(constants, point_estimates, mirror_samples, mf):
ift.MetricGaussianKL.make(**args)
return
kl = ift.MetricGaussianKL.make(**args)
assert_(len(ic.history) > 0)
assert_(len(ic.history) == len(ic.history.time_stamps))
assert_(len(ic.history) == len(ic.history.energy_values))
myassert(len(ic.history) > 0)
myassert(len(ic.history) == len(ic.history.time_stamps))
myassert(len(ic.history) == len(ic.history.energy_values))
ic.history.reset()
assert_(len(ic.history) == 0)
assert_(len(ic.history) == len(ic.history.time_stamps))
assert_(len(ic.history) == len(ic.history.energy_values))
myassert(len(ic.history) == 0)
myassert(len(ic.history) == len(ic.history.time_stamps))
myassert(len(ic.history) == len(ic.history.energy_values))
locsamp = kl._local_samples
if isinstance(mean0, ift.MultiField):
......@@ -74,7 +75,7 @@ def test_kl(constants, point_estimates, mirror_samples, mf):
# Test number of samples
expected_nsamps = 2*nsamps if mirror_samples else nsamps
assert_(len(tuple(kl.samples)) == expected_nsamps)
myassert(len(tuple(kl.samples)) == expected_nsamps)
# Test value
assert_allclose(kl.value, klpure.value)
......
......@@ -17,7 +17,7 @@
import numpy as np
import pytest
from numpy.testing import assert_, assert_allclose
from numpy.testing import assert_allclose
import nifty7 as ift
from .common import setup_function, teardown_function
......@@ -44,7 +44,7 @@ def test_special_gradients():
assert_allclose(
_lin2grad(ift.Linearization.make_var(0*f).ptw("sinc")), np.zeros(s.shape))
assert_(np.isnan(_lin2grad(ift.Linearization.make_var(0*f).ptw("abs"))))
ift.myassert(np.isnan(_lin2grad(ift.Linearization.make_var(0*f).ptw("abs"))))
assert_allclose(
_lin2grad(ift.Linearization.make_var(0*f + 10).ptw("abs")),
np.ones(s.shape))
......
......@@ -18,7 +18,7 @@
import numpy as np
import pytest
from mpi4py import MPI
from numpy.testing import assert_, assert_equal, assert_raises
from numpy.testing import assert_equal, assert_raises
import nifty7 as ift
......@@ -84,8 +84,8 @@ def test_kl(constants, point_estimates, mirror_samples, mode, mf):
# Test number of samples
expected_nsamps = 2*nsamps if mirror_samples else nsamps
assert_(len(tuple(kl0.samples)) == expected_nsamps)
assert_(len(tuple(kl1.samples)) == expected_nsamps)
ift.myassert(len(tuple(kl0.samples)) == expected_nsamps)
ift.myassert(len(tuple(kl1.samples)) == expected_nsamps)
# Test value
assert_equal(kl0.value, kl1.value)
......
......@@ -16,14 +16,16 @@
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
from numpy.testing import assert_, assert_allclose
import numpy as np
from copy import deepcopy
import numpy as np
from numpy.testing import assert_allclose
import nifty7 as ift
class CountingOp(ift.Operator):
#FIXME: Not a LinearOperator since ChainOps not supported yet
# FIXME: Not a LinearOperator since ChainOps not supported yet
def __init__(self, domain):
self._domain = self._target = ift.sugar.makeDomain(domain)
self._count = 0
......@@ -56,6 +58,6 @@ def test_operator_tree_optimiser():
op_orig = deepcopy(op)
op = ift.operator_tree_optimiser._optimise_operator(op)
assert_allclose(op(fld).val, op_orig(fld).val, rtol=np.finfo(np.float64).eps)
assert_(1 == ( (cop4.count-1) * cop3.count * cop2.count * cop1.count))
ift.myassert(1 == ((cop4.count-1) * cop3.count * cop2.count * cop1.count))
# test testing
ift.optimise_operator(op_orig)
......@@ -17,7 +17,7 @@
import numpy as np
import pytest
from numpy.testing import assert_, assert_allclose
from numpy.testing import assert_allclose
import nifty7 as ift
......@@ -71,11 +71,11 @@ def testAmplitudesInvariants(sspace, N):
astds = 0.2, 1.2
offset_std_mean = 1.3
fa = ift.CorrelatedFieldMaker.make(1.2, offset_std_mean, 1e-2, '', N,
fa = ift.CorrelatedFieldMaker.make(1.2, (offset_std_mean, 1e-2), '', N,
dofdex1)
fa.add_fluctuations(sspace, astds[0], 1e-2, 1.1, 2., 2.1, .5, -2, 1.,
fa.add_fluctuations(sspace, (astds[0], 1e-2), (1.1, 2.), (2.1, .5), (-2, 1.),
'spatial', dofdex=dofdex2)
fa.add_fluctuations(fsspace, astds[1], 1e-2, 3.1, 1., .5, .1, -4, 1.,
fa.add_fluctuations(fsspace, (astds[1], 1e-2), (3.1, 1.), (.5, .1), (-4, 1.),
'freq', dofdex=dofdex3)
op = fa.finalize()
......@@ -103,19 +103,19 @@ def testAmplitudesInvariants(sspace, N):
assert_allclose(slice_fluct_std0, sl_fluct_space, rtol=0.5)
assert_allclose(slice_fluct_std1, sl_fluct_freq, rtol=0.5)
fa = ift.CorrelatedFieldMaker.make(0., offset_std_mean, .1, '', N, dofdex1)
fa.add_fluctuations(fsspace, astds[1], 1., 3.1, 1., .5, .1, -4, 1., 'freq',
fa = ift.CorrelatedFieldMaker.make(0., (offset_std_mean, .1), '', N, dofdex1)
fa.add_fluctuations(fsspace, (astds[1], 1.), (3.1, 1.), (.5, .1), (-4, 1.), 'freq',
dofdex=dofdex3)
m = 3.
x = fa.moment_slice_to_average(m)
fa.add_fluctuations(sspace, x, 1.5, 1.1, 2., 2.1, .5, -2, 1., 'spatial', 0,
fa.add_fluctuations(sspace, (x, 1.5), (1.1, 2.), (2.1, .5), (-2, 1.), 'spatial', 0,
dofdex=dofdex2)
op = fa.finalize()
em, estd = _stats(fa.slice_fluctuation(0), samples)
assert_allclose(m, em, rtol=0.5)
assert_(op.target[-2] == sspace)
assert_(op.target[-1] == fsspace)
assert op.target[-2] == sspace
assert op.target[-1] == fsspace
for ampl in fa.normalized_amplitudes:
ift.extra.check_operator(ampl, 0.1*ift.from_random(ampl.domain), ntries=10)
......@@ -124,71 +124,59 @@ def testAmplitudesInvariants(sspace, N):
@pmp('seed', [42, 31])
@pmp('domain', spaces)
def test_complicated_vs_simple(seed, domain):
@pmp('without', (('asperity', ), ('flexibility', ), ('flexibility', 'asperity')))
def test_complicated_vs_simple(seed, domain, without):
with ift.random.Context(seed):
offset_mean = _rand()
offset_std_mean = _posrand()
offset_std_std = _posrand()
fluctuations_mean = _posrand()
fluctuations_stddev = _posrand()
flexibility_mean = _posrand()
flexibility_stddev = _posrand()
asperity_mean = _posrand()
asperity_stddev = _posrand()
loglogavgslope_mean = _posrand()
loglogavgslope_stddev = _posrand()
offset_std = _posrand(), _posrand()
fluctuations = _posrand(), _posrand()
if "flexibility" in without:
flexibility = None
else:
flexibility = _posrand(), _posrand()
if "asperity" in without:
asperity = None
else:
asperity = _posrand(), _posrand()
loglogavgslope = _posrand(), _posrand()
prefix = 'foobar'
hspace = domain.get_default_codomain()
scf = ift.SimpleCorrelatedField(
scf_args = (
domain,
offset_mean, (offset_std_mean, offset_std_std),
(fluctuations_mean, fluctuations_stddev),
(flexibility_mean, flexibility_stddev),
(asperity_mean, asperity_stddev),
(loglogavgslope_mean, loglogavgslope_stddev),
prefix=prefix,
harmonic_partner=hspace)
cfm = ift.CorrelatedFieldMaker.make(offset_mean, offset_std_mean,
offset_std_std, prefix)
cfm.add_fluctuations(domain,
fluctuations_mean,
fluctuations_stddev,
flexibility_mean,
flexibility_stddev,
asperity_mean,
asperity_stddev,
loglogavgslope_mean,
loglogavgslope_stddev,
prefix='',
offset_mean,
offset_std,
fluctuations,
flexibility,
asperity,
loglogavgslope
)
add_fluct_args = (
domain,
fluctuations,
flexibility,
asperity,
loglogavgslope
)
cfm = ift.CorrelatedFieldMaker.make(offset_mean, offset_std, prefix)
if asperity is not None and flexibility is None:
with pytest.raises(ValueError):
scf = ift.SimpleCorrelatedField(*scf_args, prefix=prefix,
harmonic_partner=hspace)
with pytest.raises(ValueError):
cfm.add_fluctuations(*add_fluct_args, prefix='',
harmonic_partner=hspace)
return
scf = ift.SimpleCorrelatedField(*scf_args, prefix=prefix,
harmonic_partner=hspace)
cfm.add_fluctuations(*add_fluct_args, prefix='',
harmonic_partner=hspace)
inp = ift.from_random(scf.domain)
op1 = cfm.finalize()
assert_(scf.domain is op1.domain)
assert scf.domain is op1.domain
ift.extra.assert_allclose(scf(inp), op1(inp))
ift.extra.check_operator(scf, inp, ntries=10)
op1 = cfm.amplitude
op0 = scf.amplitude
assert_(op0.domain is op1.domain)
assert op0.domain is op1.domain
ift.extra.assert_allclose(op0.force(inp), op1.force(inp))
@pmp('asperity', [None, (_posrand(), _posrand())])
@pmp('flexibility', [None, (_posrand(), _posrand())])
def test_simple_without_asp_fluct(asperity, flexibility):
domain = ift.RGSpace((4, 4), (0.123, 0.4))
offset_mean = _rand()
offset_std = _posrand(), _posrand()
fluctuations = _posrand(), _posrand()
loglogavgslope = _posrand(), _posrand()
prefix = 'foobar'
hspace = domain.get_default_codomain()
args = (domain, offset_mean, offset_std, fluctuations, flexibility,
asperity, loglogavgslope, prefix, hspace)
if asperity is not None and flexibility is None:
with pytest.raises(ValueError):
scf = ift.SimpleCorrelatedField(*args)
else:
scf = ift.SimpleCorrelatedField(*args)
inp = ift.from_random(scf.domain)
ift.extra.check_operator(scf, inp, ntries=10)
......@@ -17,10 +17,10 @@
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
import numpy as np
from numpy.testing import assert_, assert_allclose
from numpy.testing import assert_allclose
import nifty7 as ift
from nifty7.extra import check_operator, check_linear_operator
from nifty7.extra import check_linear_operator, check_operator
from ..common import list2fixture, setup_function, teardown_function
......@@ -42,7 +42,7 @@ def test_linear_einsum_outer(space1, space2, dtype, n_invocations=10):
ss = "i,ij,j->ij"
key_order = ("dom01", "dom02")
le = ift.LinearEinsum(space2, mf, ss, key_order=key_order)
assert_(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
ift.myassert(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
le_ift = ift.DiagonalOperator(mf["dom01"], domain=mf_dom["dom02"], spaces=0) @ ift.DiagonalOperator(mf["dom02"])
le_ift = le_ift @ ift.OuterProduct(ift.DomainTuple.make(mf_dom["dom02"][1]),
......@@ -63,7 +63,7 @@ def test_linear_einsum_contraction(space1, space2, dtype, n_invocations=10):
ss = "i,ij,j->i"
key_order = ("dom01", "dom02")
le = ift.LinearEinsum(space2, mf, ss, key_order=key_order)
assert_(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
ift.myassert(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
le_ift = ift.ContractionOperator(mf_dom["dom02"], 1)
le_ift = le_ift @ ift.DiagonalOperator(mf["dom01"], domain=mf_dom["dom02"], spaces=0)
......@@ -116,7 +116,7 @@ def test_linear_einsum_transpose(space1, space2, dtype, n_invocations=10):
mf = ift.MultiField.from_dict({})
ss = "ij->ji"
le = ift.LinearEinsum(dom, mf, ss)
assert_(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
ift.myassert(check_linear_operator(le, domain_dtype=dtype, target_dtype=dtype) is None)
# SwitchSpacesOperator is equivalent to LinearEinsum with "ij->ji"
le_ift = _SwitchSpacesOperator(dom, 1)
......
......@@ -17,7 +17,7 @@
import numpy as np
import pytest
from numpy.testing import assert_, assert_allclose
from numpy.testing import assert_allclose
import nifty7 as ift
......@@ -63,7 +63,7 @@ def test_fft1D(d, dtype, op):
@pmp('nthreads', [-1, 1, 2, 3, 4])
def test_fft2D(dim1, dim2, d1, d2, dtype, op, nthreads):
ift.fft.set_nthreads(nthreads)
assert_(ift.fft.nthreads() == nthreads)
ift.myassert(ift.fft.nthreads() == nthreads)
tol = _get_rtol(dtype)
a = ift.RGSpace([dim1, dim2], distances=[d1, d2])
b = ift.RGSpace(
......
......@@ -17,9 +17,9 @@
import numpy as np
import pytest
from numpy.testing import assert_
import nifty7 as ift
from ..common import setup_function, teardown_function
pmp = pytest.mark.parametrize
......@@ -57,7 +57,7 @@ def test_gridding(nu, nv, N, eps):
for i in range(N):
dft += (
vis[i]*np.exp(2j*np.pi*(x*uv[i, 0]*dstx + y*uv[i, 1]*dsty))).real
assert_(_l2error(dft, pynu) < eps)
ift.myassert(_l2error(dft, pynu) < eps)
def test_cartesian():
......
......@@ -17,7 +17,7 @@
import numpy as np
import pytest
from numpy.testing import assert_, assert_allclose
from numpy.testing import assert_allclose
import nifty7 as ift
......@@ -40,9 +40,9 @@ def test_part_mf_insert():
op = a.partial_insert(b)
fld = ift.from_random(op.domain, 'normal')
ift.extra.check_operator(op, fld, ntries=ntries)
assert_(op.domain is ift.MultiDomain.union(
ift.myassert(op.domain is ift.MultiDomain.union(
[op1.domain, op2.domain, op4.domain, op5.domain]))
assert_(op.target is ift.MultiDomain.union(
ift.myassert(op.target is ift.MultiDomain.union(
[op1.target, op2.target, op3.target, op5.target]))
x, y = fld.val, op(fld).val
assert_allclose(y['a1'], x['a']*1.32)
......
......@@ -15,7 +15,7 @@
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
from numpy.testing import assert_, assert_allclose, assert_raises
from numpy.testing import assert_allclose, assert_raises
import nifty7 as ift
from nifty7.operators.simplify_for_const import ConstantOperator
......@@ -26,7 +26,7 @@ def test_simplification():
f1 = ift.full(dom, 2.)
op = ift.FFTOperator(f1.domain["a"]).ducktape("a")
_, op2 = op.simplify_for_constant_input(f1)
assert_(isinstance(op2, ConstantOperator))
ift.myassert(isinstance(op2, ConstantOperator))
assert_allclose(op(f1).val, op2.force(f1).val)
dom = {"a": ift.RGSpace(10), "b": ift.RGSpace(5)}
......
......@@ -17,9 +17,9 @@
import numpy as np
import pytest
from numpy.testing import assert_
import nifty7 as ift
from ..common import setup_function, teardown_function
......@@ -38,5 +38,5 @@ def test_value_inserter(sp, seed):
f = ift.from_random(op.domain, 'normal')
inp = f.val
ret = op(f).val
assert_(ret[ind] == inp)
assert_(np.sum(ret) == inp)
ift.myassert(ret[ind] == inp)
ift.myassert(np.sum(ret) == inp)
......@@ -19,10 +19,10 @@ import itertools
import numpy as np
import pytest
from numpy.testing import (assert_, assert_almost_equal, assert_equal,
assert_raises)
from numpy.testing import assert_almost_equal, assert_equal, assert_raises
from nifty7 import GLSpace, myassert
from nifty7 import GLSpace
from ..common import setup_function, teardown_function
pmp = pytest.mark.parametrize
......@@ -56,7 +56,7 @@ def get_dvol_configs():
@pmp('attribute', ['nlat', 'nlon'])
def test_property_ret_type(attribute):