Commit 74c2ad71 authored by Gordian Edenhofer's avatar Gordian Edenhofer

Simplify arguments to the correlated field model

parent ab97920a
......@@ -135,7 +135,7 @@
"## Before the Action: The Moment-Matched Log-Normal Distribution\n",
"Many properties of the correlated field are modelled as being lognormally distributed.\n",
"\n",
"The distribution models are parametrized via their means `_mean` and standard-deviations `_stddev`.\n",
"The distribution models are parametrized via their means and standard-deviations (first and second position in tuple).\n",
"\n",
"To get a feeling of how the ratio of the `mean` and `stddev` parameters influences the distribution shape,\n",
"here are a few example histograms: (observe the x-axis!)"
......@@ -189,21 +189,16 @@
"# Neutral model parameters yielding a quasi-constant field\n",
"cf_make_pars = {\n",
" 'offset_mean': 0.,\n",
" 'offset_std_mean': 1e-3,\n",
" 'offset_std_std': 1e-16,\n",
" 'offset_std': (1e-3, 1e-16),\n",
" 'prefix': ''\n",
"}\n",
"\n",
"cf_x_fluct_pars = {\n",
" 'target_subdomain': x_space,\n",
" 'fluctuations_mean': 1e-3,\n",
" 'fluctuations_stddev': 1e-16,\n",
" 'flexibility_mean': 1e-3,\n",
" 'flexibility_stddev': 1e-16,\n",
" 'asperity_mean': 1e-3,\n",
" 'asperity_stddev': 1e-16,\n",
" 'loglogavgslope_mean': 0.,\n",
" 'loglogavgslope_stddev': 1e-16\n",
" 'fluctuations': (1e-3, 1e-16),\n",
" 'flexibility': (1e-3, 1e-16),\n",
" 'asperity': (1e-3, 1e-16),\n",
" 'loglogavgslope': (0., 1e-16)\n",
"}\n",
"\n",
"init_model(cf_make_pars, cf_x_fluct_pars)"
......@@ -225,18 +220,18 @@
"source": [
"# Parameter Showcases\n",
"\n",
"## The `fluctuations_` parameters of `add_fluctuations()`\n",
"## The `fluctuations` parameters of `add_fluctuations()`\n",
"\n",
"determine the **amplitude of variations along the field dimension**\n",
"for which `add_fluctuations` is called.\n",
"\n",
"`fluctuations_mean` set the _average_ amplitude of the fields fluctuations along the given dimension,\\\n",
"`fluctuations_stddev` sets the width and shape of the amplitude distribution.\n",
"`fluctuations[0]` set the _average_ amplitude of the fields fluctuations along the given dimension,\\\n",
"`fluctuations[1]` sets the width and shape of the amplitude distribution.\n",
"\n",
"The amplitude is modelled as being log-normally distributed,\n",
"see `The Moment-Matched Log-Normal Distribution` above for details.\n",
"\n",
"#### `fluctuations_mean`:"
"#### `fluctuations` mean:"
]
},
{
......@@ -245,14 +240,14 @@
"metadata": {},
"outputs": [],
"source": [
"vary_parameter('fluctuations_mean', [0.05, 0.5, 2.], samples_vary_in='xi')"
"vary_parameter('fluctuations', [(0.05, 1e-16), (0.5, 1e-16), (2., 1e-16)], samples_vary_in='xi')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `fluctuations_stddev`:"
"#### `fluctuations` std:"
]
},
{
......@@ -261,21 +256,21 @@
"metadata": {},
"outputs": [],
"source": [
"cf_x_fluct_pars['fluctuations_mean'] = 1.0\n",
"vary_parameter('fluctuations_stddev', [0.01, 0.1, 1.0], samples_vary_in='fluctuations')"
"vary_parameter('fluctuations', [(1., 0.01), (1., 0.1), (1., 1.)], samples_vary_in='fluctuations')\n",
"cf_x_fluct_pars['fluctuations'] = (1., 1e-16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The `loglogavgslope_` parameters of `add_fluctuations()`\n",
"## The `loglogavgslope` parameters of `add_fluctuations()`\n",
"\n",
"determine **the slope of the loglog-linear (power law) component of the power spectrum**.\n",
"\n",
"The slope is modelled to be normally distributed.\n",
"\n",
"#### `loglogavgslope_mean`:"
"#### `loglogavgslope` mean:"
]
},
{
......@@ -284,14 +279,14 @@
"metadata": {},
"outputs": [],
"source": [
"vary_parameter('loglogavgslope_mean', [-3., -1., 1.], samples_vary_in='xi')"
"vary_parameter('loglogavgslope', [(-3., 1e-16), (-1., 1e-16), (1., 1e-16)], samples_vary_in='xi')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `loglogavgslope_stddev`:"
"#### `loglogavgslope` std:"
]
},
{
......@@ -300,25 +295,25 @@
"metadata": {},
"outputs": [],
"source": [
"cf_x_fluct_pars['loglogavgslope_mean'] = -1.0\n",
"vary_parameter('loglogavgslope_stddev', [0.01, 0.1, 1.0], samples_vary_in='loglogavgslope')"
"vary_parameter('loglogavgslope', [(-1., 0.01), (-1., 0.1), (-1., 1.0)], samples_vary_in='loglogavgslope')\n",
"cf_x_fluct_pars['loglogavgslope'] = (-1., 1e-16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The `flexibility_` parameters of `add_fluctuations()`\n",
"## The `flexibility` parameters of `add_fluctuations()`\n",
"\n",
"determine **the amplitude of the integrated Wiener process component of the power spectrum**\n",
"(how strong the power spectrum varies besides the power-law).\n",
"\n",
"`flexibility_mean` sets the _average_ amplitude of the i.g.p. component,\n",
"`flexibility_stddev` sets how much the amplitude can vary.\\\n",
"`flexibility[0]` sets the _average_ amplitude of the i.g.p. component,\\\n",
"`flexibility[1]` sets how much the amplitude can vary.\\\n",
"These two parameters feed into a moment-matched log-normal distribution model,\n",
"see above for a demo of its behavior.\n",
"\n",
"#### `flexibility_mean`:"
"#### `flexibility` mean:"
]
},
{
......@@ -327,14 +322,14 @@
"metadata": {},
"outputs": [],
"source": [
"vary_parameter('flexibility_mean', [0.1, 1.0, 3.0], samples_vary_in='spectrum')"
"vary_parameter('flexibility', [(0.1, 1e-16), (1.0, 1e-16), (3.0, 1e-16)], samples_vary_in='spectrum')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `flexibility_stddev`:"
"#### `flexibility` std:"
]
},
{
......@@ -343,23 +338,23 @@
"metadata": {},
"outputs": [],
"source": [
"cf_x_fluct_pars['flexibility_mean'] = 2.0\n",
"vary_parameter('flexibility_stddev', [0.01, 0.1, 1.0], samples_vary_in='flexibility')"
"vary_parameter('flexibility', [(2., 0.01), (2., 0.1), (2., 1.)], samples_vary_in='flexibility')\n",
"cf_x_fluct_pars['flexibility'] = (2., 1e-16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The `asperity_` parameters of `add_fluctuations()`\n",
"## The `asperity` parameters of `add_fluctuations()`\n",
"\n",
"`asperity_` determines **how rough the integrated Wiener process component of the power spectrum is**.\n",
"`asperity` determines **how rough the integrated Wiener process component of the power spectrum is**.\n",
"\n",
"`asperity_mean` sets the average roughness, `asperity_stddev` sets how much the roughness can vary.\\\n",
"`asperity[0]` sets the average roughness, `asperity[1]` sets how much the roughness can vary.\\\n",
"These two parameters feed into a moment-matched log-normal distribution model,\n",
"see above for a demo of its behavior.\n",
"\n",
"#### `asperity_mean`:"
"#### `asperity` mean:"
]
},
{
......@@ -368,14 +363,14 @@
"metadata": {},
"outputs": [],
"source": [
"vary_parameter('asperity_mean', [0.001, 1.0, 5.0], samples_vary_in='spectrum')"
"vary_parameter('asperity', [(0.001, 1e-16), (1.0, 1e-16), (5., 1e-16)], samples_vary_in='spectrum')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `asperity_stddev`:"
"#### `asperity` std:"
]
},
{
......@@ -384,8 +379,8 @@
"metadata": {},
"outputs": [],
"source": [
"cf_x_fluct_pars['asperity_mean'] = 1.0\n",
"vary_parameter('asperity_stddev', [0.01, 0.1, 1.0], samples_vary_in='asperity')"
"vary_parameter('asperity', [(1., 0.01), (1., 0.1), (1., 1.)], samples_vary_in='asperity')\n",
"cf_x_fluct_pars['asperity'] = (1., 1e-16)"
]
},
{
......@@ -406,10 +401,10 @@
"outputs": [],
"source": [
"# Reset model to neutral\n",
"cf_x_fluct_pars['fluctuations_mean'] = 1e-3\n",
"cf_x_fluct_pars['flexibility_mean'] = 1e-3\n",
"cf_x_fluct_pars['asperity_mean'] = 1e-3\n",
"cf_x_fluct_pars['loglogavgslope_mean'] = 1e-3"
"cf_x_fluct_pars['fluctuations'] = (1e-3, 1e-16)\n",
"cf_x_fluct_pars['flexibility'] = (1e-3, 1e-16)\n",
"cf_x_fluct_pars['asperity'] = (1e-3, 1e-16)\n",
"cf_x_fluct_pars['loglogavgslope'] = (1e-3, 1e-16)"
]
},
{
......@@ -425,15 +420,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## The `offset_std_` parameters of `CorrelatedFieldMaker.make()`\n",
"## The `offset_std` parameters of `CorrelatedFieldMaker.make()`\n",
"\n",
"Variation of the global offset of the field are modelled as being log-normally distributed.\n",
"See `The Moment-Matched Log-Normal Distribution` above for details.\n",
"\n",
"The `offset_std_mean` parameter sets how much NIFTy will vary the offset *on average*.\\\n",
"The `offset_std_std` parameters defines the with and shape of the offset variation distribution.\n",
"The `offset_std[0]` parameter sets how much NIFTy will vary the offset *on average*.\\\n",
"The `offset_std[1]` parameters defines the with and shape of the offset variation distribution.\n",
"\n",
"#### `offset_std_mean`:"
"#### `offset_std` mean:"
]
},
{
......@@ -442,14 +437,14 @@
"metadata": {},
"outputs": [],
"source": [
"vary_parameter('offset_std_mean', [1e-16, 0.5, 2.], samples_vary_in='xi')"
"vary_parameter('offset_std', [(1e-16, 1e-16), (0.5, 1e-16), (2., 1e-16)], samples_vary_in='xi')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `offset_std_std`:"
"#### `offset_std` std:"
]
},
{
......@@ -458,8 +453,7 @@
"metadata": {},
"outputs": [],
"source": [
"cf_make_pars['offset_std_mean'] = 1.0\n",
"vary_parameter('offset_std_std', [0.01, 0.1, 1.0], samples_vary_in='zeromode')"
"vary_parameter('offset_std', [(1., 0.01), (1., 0.1), (1., 1.)], samples_vary_in='zeromode')"
]
}
],
......@@ -479,7 +473,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.2"
"version": "3.8.3"
}
},
"nbformat": 4,
......
......@@ -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]
......
......@@ -358,18 +358,16 @@ class CorrelatedFieldMaker:
self._total_N = total_N
@staticmethod
def make(offset_mean, offset_std_mean, offset_std_std, prefix, total_N=0,
dofdex=None):
def make(offset_mean, offset_std, prefix, total_N=0, dofdex=None):
"""Returns a CorrelatedFieldMaker object.
Parameters
----------
offset_mean : float
Mean offset from zero of the correlated field to be made.
offset_std_mean : float
Mean standard deviation of the offset.
offset_std_std : float
Standard deviation of the stddev of the offset.
offset_std : tuple of float
Mean standard deviation and standard deviation of the standard
deviation of the offset. No, this is not a word duplication.
prefix : string
Prefix to the names of the domains of the cf operator to be made.
This determines the names of the operator domain.
......@@ -392,22 +390,19 @@ class CorrelatedFieldMaker:
elif len(dofdex) != total_N:
raise ValueError("length of dofdex needs to match total_N")
N = max(dofdex) + 1 if total_N > 0 else 0
zm = LognormalTransform(offset_std_mean, offset_std_std,
prefix + 'zeromode', N)
if len(offset_std) != 2:
raise TypeError
zm = LognormalTransform(*offset_std, prefix + 'zeromode', N)
if total_N > 0:
zm = _Distributor(dofdex, zm.target, UnstructuredDomain(total_N)) @ zm
return CorrelatedFieldMaker(offset_mean, zm, prefix, total_N)
def add_fluctuations(self,
target_subdomain,
fluctuations_mean,
fluctuations_stddev,
flexibility_mean,
flexibility_stddev,
asperity_mean,
asperity_stddev,
loglogavgslope_mean,
loglogavgslope_stddev,
fluctuations,
flexibility,
asperity,
loglogavgslope,
prefix='',
index=None,
dofdex=None,
......@@ -435,14 +430,14 @@ class CorrelatedFieldMaker:
:class:`~nifty7.domain_tuple.DomainTuple`
Target subdomain on which the correlation structure defined
in this call should hold.
fluctuations_{mean,stddev} : float
fluctuations : tuple of float
Total spectral energy -> Amplitude of the fluctuations
flexibility_{mean,stddev} : float
flexibility : tuple of float or None
Amplitude of the non-power-law power spectrum component
asperity_{mean,stddev} : float
asperity : tuple of float or None
Roughness of the non-power-law power spectrum component
Used to accommodate single frequency peaks
loglogavgslope_{mean,stddev} : float
loglogavgslope : tuple of float
Power law component exponent
prefix : string
prefix of the power spectrum parameter domain names
......@@ -478,37 +473,37 @@ class CorrelatedFieldMaker:
else:
N = 0
target_subdomain = makeDomain(target_subdomain)
prefix = str(prefix)
# assert isinstance(target_subdomain[space], (RGSpace, HPSpace, GLSpace)
# assert isinstance(target_subdomain[space], (RGSpace, HPSpace, GLSpace))
for arg in [fluctuations, loglogavgslope]:
if len(arg) != 2:
raise TypeError
for kw, arg in [("flexibility", flexibility), ("asperity", asperity)]:
if arg is None:
continue
if len(arg) != 2:
raise TypeError
if len(arg) == 2 and (arg[0] <= 0. or arg[1] <= 0.):
ve = "{0} must be strictly positive (or None)"
raise ValueError(ve.format(kw))
if flexibility is None and asperity is not None:
raise ValueError("flexibility may not be disabled on its own")
ve = "{0}_mean and {0}_stddev must be strictly positive (or both zero to disable {0})"
if fluctuations_mean > 0. and fluctuations_stddev > 0.:
fluct = LognormalTransform(fluctuations_mean, fluctuations_stddev,
self._prefix + prefix + 'fluctuations', N)
pre = self._prefix + str(prefix)
fluct = LognormalTransform(*fluctuations, pre + 'fluctuations', N)
if flexibility is not None:
flex = LognormalTransform(*flexibility, pre + 'flexibility', N)
else:
raise ValueError(ve.format("fluctuations"))
if flexibility_mean == 0. and flexibility_stddev == 0.:
if asperity_mean != 0. or asperity_stddev != 0.:
raise ValueError("flexibility may not be disabled on its own")
flex = None
elif flexibility_mean > 0. and flexibility_stddev > 0.:
flex = LognormalTransform(flexibility_mean, flexibility_stddev,
self._prefix + prefix + 'flexibility', N)
if asperity is not None:
asp = LognormalTransform(*asperity, pre + 'asperity', N)
else:
raise ValueError(ve.format("flexibility"))
if asperity_mean == 0. and asperity_stddev == 0.:
asp = None
elif asperity_mean > 0. and asperity_stddev > 0.:
asp = LognormalTransform(asperity_mean, asperity_stddev,
self._prefix + prefix + 'asperity', N)
else:
raise ValueError(ve.format("asperity"))
avgsl = NormalTransform(loglogavgslope_mean, loglogavgslope_stddev,
self._prefix + prefix + 'loglogavgslope', N)
avgsl = NormalTransform(*loglogavgslope, pre + 'loglogavgslope', N)
amp = _Amplitude(PowerSpace(harmonic_partner), fluct, flex, asp, avgsl,
self._azm, target_subdomain[-1].total_volume,
self._prefix + prefix + 'spectrum', dofdex)
pre + 'spectrum', dofdex)
if index is not None:
self._a.insert(index, amp)
......
......@@ -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,12 +103,12 @@ 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)
......@@ -148,17 +148,14 @@ def test_complicated_vs_simple(seed, domain):
(loglogavgslope_mean, loglogavgslope_stddev),
prefix=prefix,
harmonic_partner=hspace)
cfm = ift.CorrelatedFieldMaker.make(offset_mean, offset_std_mean,
offset_std_std, prefix)
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,
(fluctuations_mean, fluctuations_stddev),
(flexibility_mean, flexibility_stddev),
(asperity_mean, asperity_stddev),
(loglogavgslope_mean, loglogavgslope_stddev),
prefix='',
harmonic_partner=hspace)
inp = ift.from_random(scf.domain)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment