Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Neel Shah
NIFTy
Commits
92638ed6
Commit
92638ed6
authored
Nov 06, 2019
by
Philipp Arras
Browse files
Remove old files
parent
346cb2a2
Changes
9
Hide whitespace changes
Inline
Side-by-side
demos/newamplitudes
/easyinterface
.py
→
demos/newamplitudes.py
View file @
92638ed6
File moved
demos/newamplitudes/correlated_fields_normalized_amplitude.py
deleted
100644 → 0
View file @
346cb2a2
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright(C) 2013-2019 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
import
nifty5
as
ift
if
__name__
==
'__main__'
:
import
numpy
as
np
np
.
random
.
seed
(
42
)
nspecs
=
2
a
=
[]
spaces
=
[]
for
_
in
range
(
nspecs
):
ndim
=
2
sspace
=
ift
.
RGSpace
(
np
.
linspace
(
16
,
20
,
num
=
ndim
).
astype
(
np
.
int
),
np
.
linspace
(
2.3
,
7.99
,
num
=
ndim
))
hspace
=
sspace
.
get_default_codomain
()
spaces
.
append
(
sspace
)
target
=
ift
.
PowerSpace
(
hspace
)
a
.
append
(
ift
.
NormalizedAmplitude
(
target
,
16
,
1
,
1
,
-
3
,
1
,
0
,
1
,
0
,
1
))
tgt
=
ift
.
makeDomain
(
tuple
(
spaces
))
op
=
ift
.
CorrelatedFieldNormAmplitude
(
tgt
,
a
,
0.
,
1.
)
fld
=
ift
.
from_random
(
'normal'
,
op
.
domain
)
ift
.
extra
.
check_jacobian_consistency
(
op
,
fld
)
demos/newamplitudes/normalized_amplitude.py
deleted
100644 → 0
View file @
346cb2a2
import
numpy
as
np
import
nifty5
as
ift
if
__name__
==
'__main__'
:
np
.
random
.
seed
(
42
)
ndim
=
1
sspace
=
ift
.
RGSpace
(
np
.
linspace
(
16
,
20
,
num
=
ndim
).
astype
(
np
.
int
),
np
.
linspace
(
2.3
,
7.99
,
num
=
ndim
))
hspace
=
sspace
.
get_default_codomain
()
target
=
ift
.
PowerSpace
(
hspace
)
op
=
ift
.
NormalizedAmplitude
(
target
,
16
,
1
,
1
,
-
3
,
1
,
0
,
1
,
0
,
1
)
if
not
isinstance
(
op
.
target
[
0
],
ift
.
PowerSpace
):
raise
RuntimeError
fld
=
ift
.
from_random
(
'normal'
,
op
.
domain
)
ift
.
extra
.
check_jacobian_consistency
(
op
,
fld
)
pd
=
ift
.
PowerDistributor
(
hspace
,
power_space
=
target
)
ht
=
ift
.
HartleyOperator
(
pd
.
target
)
if
np
.
testing
.
assert_allclose
((
pd
@
op
)(
fld
).
integrate
(),
1
):
raise
RuntimeError
if
np
.
testing
.
assert_allclose
(
(
ht
@
pd
@
op
)(
fld
).
to_global_data
()[
ndim
*
(
0
,)],
1
):
raise
RuntimeError
demos/newamplitudes/wiener_process_integrated_amplitude.py
deleted
100644 → 0
View file @
346cb2a2
import
nifty5
as
ift
import
numpy
as
np
def
mfplot
(
fld
,
A1
,
A2
,
name
):
p
=
ift
.
Plot
()
dom
=
fld
.
domain
mi
,
ma
=
np
.
min
(
fld
.
val
),
np
.
max
(
fld
.
val
)
for
ii
in
range
(
dom
.
shape
[
-
1
]):
extr
=
ift
.
DomainTupleFieldInserter
(
op
.
target
,
1
,
(
ii
,)).
adjoint
p
.
add
(
extr
(
fld
),
zmin
=
mi
,
zmax
=
ma
)
p
.
add
(
A1
)
p
.
add
(
A2
)
p
.
add
(
fld
)
p
.
output
(
name
=
name
,
xsize
=
14
,
ysize
=
14
)
if
__name__
==
'__main__'
:
np
.
random
.
seed
(
42
)
sspace
=
ift
.
RGSpace
((
512
,
512
))
hspace
=
sspace
.
get_default_codomain
()
target
=
ift
.
PowerSpace
(
hspace
,
ift
.
PowerSpace
.
useful_binbounds
(
hspace
,
True
))
# A = Amplitude(target, [5, -3, 1, 0], [1, 1, 1, 0.5],
# ['rest', 'smooth', 'wienersigma'])
# fld = ift.from_random('normal', A.domain)
# ift.extra.check_jacobian_consistency(A, fld)
# op = CorrelatedFieldNormAmplitude(sspace, A, 3, 2)
# plts = []
# p = ift.Plot()
# for _ in range(25):
# fld = ift.from_random('normal', op.domain)
# plts.append(A.force(fld))
# p.add(op(fld))
# p.output(name='debug1.png', xsize=20, ysize=20)
# ift.single_plot(plts, name='debug.png')
# Multifrequency
sspace1
=
ift
.
RGSpace
((
512
,
512
))
hspace1
=
sspace1
.
get_default_codomain
()
target1
=
ift
.
PowerSpace
(
hspace1
,
ift
.
PowerSpace
.
useful_binbounds
(
hspace1
,
True
))
A1
=
ift
.
WPAmplitude
(
target1
,
[
0
,
-
2
,
0
],
[
1E-5
,
1
,
1
],
1
,
0.99
,
[
'rest1'
,
'smooth1'
,
'wienersigma1'
])
sspace2
=
ift
.
RGSpace
((
20
,),
distances
=
(
1e7
))
hspace2
=
sspace2
.
get_default_codomain
()
target2
=
ift
.
PowerSpace
(
hspace2
,
ift
.
PowerSpace
.
useful_binbounds
(
hspace2
,
True
))
A2
=
ift
.
WPAmplitude
(
target2
,
[
0
,
-
2
,
0
],
[
1E-5
,
1
,
1
],
1
,
0.99
,
[
'rest2'
,
'smooth2'
,
'wienersigma2'
])
op
=
ift
.
CorrelatedFieldNormAmplitude
((
sspace1
,
sspace2
),
(
A1
,
A2
),
3
,
2
)
for
jj
in
range
(
10
):
fld
=
ift
.
from_random
(
'normal'
,
op
.
domain
)
mfplot
(
op
(
fld
),
A1
.
force
(
fld
),
A2
.
force
(
fld
),
'debug{}.png'
.
format
(
jj
))
nifty5/__init__.py
View file @
92638ed6
...
...
@@ -76,9 +76,6 @@ from .minimization.metric_gaussian_kl import MetricGaussianKL
from
.sugar
import
*
from
.plot
import
Plot
from
.library.smooth_linear_amplitude
import
(
SLAmplitude
,
LinearSLAmplitude
,
CepstrumOperator
,
WPAmplitude
)
from
.library.normalized_amplitude
import
NormalizedAmplitude
from
.library.inverse_gamma_operator
import
InverseGammaOperator
from
.library.los_response
import
LOSResponse
from
.library.dynamic_operator
import
(
dynamic_operator
,
...
...
@@ -86,11 +83,10 @@ from .library.dynamic_operator import (dynamic_operator,
from
.library.light_cone_operator
import
LightConeOperator
from
.library.wiener_filter_curvature
import
WienerFilterCurvature
from
.library.correlated_fields
import
CorrelatedField
,
MfCorrelatedField
,
CorrelatedFieldNormAmplitude
from
.library.adjust_variances
import
(
make_adjust_variances_hamiltonian
,
do_adjust_variances
)
from
.library.gridder
import
GridderMaker
from
.library.
final_amplitude
import
FinalAmplitude
from
.library.
correlated_fields
import
CorrelatedFieldMaker
from
.
import
extra
...
...
nifty5/library/correlated_fields.py
View file @
92638ed6
...
...
@@ -12,222 +12,281 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright(C) 2013-2019 Max-Planck-Society
# Authors: Philipp Frank, Philipp Arras
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
from
functools
import
reduce
from
operator
import
mul
import
numpy
as
np
from
numpy.testing
import
assert_allclose
from
..domain_tuple
import
DomainTuple
from
..domains.power_space
import
PowerSpace
from
..domains.unstructured_domain
import
UnstructuredDomain
from
..extra
import
check_jacobian_consistency
from
..field
import
Field
from
..multi_domain
import
MultiDomain
from
..operators.adder
import
Adder
from
..operators.contraction_operator
import
ContractionOperator
from
..operators.distributors
import
PowerDistributor
from
..operators.endomorphic_operator
import
EndomorphicOperator
from
..operators.harmonic_operators
import
HarmonicTransformOperator
from
..operators.linear_operator
import
LinearOperator
from
..operators.operator
import
Operator
from
..operators.simple_linear_operators
import
VdotOperator
,
ducktape
from
..sugar
import
full
,
makeOp
def
CorrelatedField
(
target
,
amplitude_operator
,
name
=
'xi'
,
codomain
=
None
):
"""Constructs an operator which turns a white Gaussian excitation field
into a correlated field.
This function returns an operator which implements:
ht @ (vol * A * xi),
where `ht` is a harmonic transform operator, `A` is the square root of the
prior covariance and `xi` is the excitation field.
Parameters
----------
target : Domain, DomainTuple or tuple of Domain
Target of the operator. Must contain exactly one space.
amplitude_operator: Operator
name : string
:class:`MultiField` key for the xi-field.
codomain : Domain
The codomain for target[0]. If not supplied, it is inferred.
Returns
-------
Operator
Correlated field
Notes
-----
In NIFTy, non-harmonic RGSpaces are by definition periodic. Therefore
the operator constructed by this method will output a correlated field
with *periodic* boundary conditions. If a non-periodic field is needed,
one needs to combine this operator with a :class:`FieldZeroPadder`.
"""
tgt
=
DomainTuple
.
make
(
target
)
if
len
(
tgt
)
>
1
:
raise
ValueError
if
codomain
is
None
:
codomain
=
tgt
[
0
].
get_default_codomain
()
h_space
=
codomain
ht
=
HarmonicTransformOperator
(
h_space
,
target
=
tgt
[
0
])
if
isinstance
(
amplitude_operator
,
Operator
):
p_space
=
amplitude_operator
.
target
[
0
]
elif
isinstance
(
amplitude_operator
,
Field
):
p_space
=
amplitude_operator
.
domain
[
0
]
else
:
raise
TypeError
power_distributor
=
PowerDistributor
(
h_space
,
p_space
)
A
=
power_distributor
(
amplitude_operator
)
vol
=
h_space
.
scalar_dvol
**-
0.5
xi
=
ducktape
(
h_space
,
None
,
name
)
# When doubling the resolution of `tgt` the value of the highest k-mode
# will scale with a square root. `vol` cancels this effect such that the
# same power spectrum can be used for the spaces with the same volume,
# different resolutions and the same object in them.
if
isinstance
(
amplitude_operator
,
Field
):
return
ht
(
makeOp
(
A
)
@
xi
).
scale
(
vol
)
return
ht
(
A
*
xi
).
scale
(
vol
)
def
MfCorrelatedField
(
target
,
amplitudes
,
name
=
'xi'
):
"""Constructs an operator which turns white Gaussian excitation fields
into a correlated field defined on a DomainTuple with two entries and two
separate correlation structures.
This operator may be used as a model for multi-frequency reconstructions
with a correlation structure in both spatial and energy direction.
Parameters
----------
target : Domain, DomainTuple or tuple of Domain
Target of the operator. Must contain exactly two spaces.
amplitudes: iterable of Operator
List of two amplitude operators.
name : string
:class:`MultiField` key for xi-field.
Returns
-------
Operator
Correlated field
Notes
-----
In NIFTy, non-harmonic RGSpaces are by definition periodic. Therefore
the operator constructed by this method will output a correlated field
with *periodic* boundary conditions. If a non-periodic field is needed,
one needs to combine this operator with a :class:`FieldZeroPadder` or even
two (one for the energy and one for the spatial subdomain)
"""
tgt
=
DomainTuple
.
make
(
target
)
if
len
(
tgt
)
!=
2
:
raise
ValueError
if
len
(
amplitudes
)
!=
2
:
raise
ValueError
hsp
=
DomainTuple
.
make
([
tt
.
get_default_codomain
()
for
tt
in
tgt
])
ht1
=
HarmonicTransformOperator
(
hsp
,
target
=
tgt
[
0
],
space
=
0
)
ht2
=
HarmonicTransformOperator
(
ht1
.
target
,
target
=
tgt
[
1
],
space
=
1
)
ht
=
ht2
@
ht1
psp
=
[
aa
.
target
[
0
]
for
aa
in
amplitudes
]
pd0
=
PowerDistributor
(
hsp
,
psp
[
0
],
0
)
pd1
=
PowerDistributor
(
pd0
.
domain
,
psp
[
1
],
1
)
pd
=
pd0
@
pd1
dd0
=
ContractionOperator
(
pd
.
domain
,
1
).
adjoint
dd1
=
ContractionOperator
(
pd
.
domain
,
0
).
adjoint
d
=
[
dd0
,
dd1
]
a
=
[
dd
@
amplitudes
[
ii
]
for
ii
,
dd
in
enumerate
(
d
)]
a
=
reduce
(
mul
,
a
)
A
=
pd
@
a
# For `vol` see comment in `CorrelatedField`
vol
=
reduce
(
mul
,
[
sp
.
scalar_dvol
**-
0.5
for
sp
in
hsp
])
return
ht
(
vol
*
A
*
ducktape
(
hsp
,
None
,
name
))
def
CorrelatedFieldNormAmplitude
(
target
,
amplitudes
,
stdmean
,
stdstd
,
names
=
[
'xi'
,
'std'
]):
"""Constructs an operator which turns white Gaussian excitation fields
into a correlated field defined on a DomainTuple with n entries and n
separate correlation structures.
This operator may be used as a model for multi-frequency reconstructions
with a correlation structure in both spatial and energy direction.
Parameters
----------
target : Domain, DomainTuple or tuple of Domain
Target of the operator. Must contain exactly n spaces.
amplitudes: Opertor, iterable of Operator
Amplitude operator if n = 1 or list of n amplitude operators.
stdmean : float
Prior mean of the overall standart deviation.
stdstd : float
Prior standart deviation of the overall standart deviation.
names : iterable of string
:class:`MultiField` keys for xi-field and std-field.
Returns
-------
Operator
Correlated field
Notes
-----
In NIFTy, non-harmonic RGSpaces are by definition periodic. Therefore
the operator constructed by this method will output a correlated field
with *periodic* boundary conditions. If a non-periodic field is needed,
one needs to combine this operator with a :class:`FieldZeroPadder` or even
two (one for the energy and one for the spatial subdomain)
"""
amps
=
[
amplitudes
,
]
if
isinstance
(
amplitudes
,
(
Operator
,
Field
))
else
amplitudes
cls
=
Operator
if
isinstance
(
amps
[
0
],
Operator
)
else
Field
assert
all
([
isinstance
(
aa
,
cls
)
for
aa
in
amps
])
tgt
=
DomainTuple
.
make
(
target
)
if
len
(
tgt
)
!=
len
(
amps
):
raise
ValueError
stdmean
,
stdstd
=
float
(
stdmean
),
float
(
stdstd
)
if
stdstd
<=
0
:
raise
ValueError
if
cls
==
Field
:
psp
=
[
aa
.
domain
[
0
]
for
aa
in
amps
]
else
:
psp
=
[
aa
.
target
[
0
]
for
aa
in
amps
]
hsp
=
DomainTuple
.
make
([
tt
.
get_default_codomain
()
for
tt
in
tgt
])
ht
=
HarmonicTransformOperator
(
hsp
,
target
=
tgt
[
0
],
space
=
0
)
pd
=
PowerDistributor
(
hsp
,
psp
[
0
],
0
)
for
i
in
range
(
1
,
len
(
amps
)):
ht
=
HarmonicTransformOperator
(
ht
.
target
,
target
=
tgt
[
i
],
space
=
i
)
@
ht
pd
=
pd
@
PowerDistributor
(
pd
.
domain
,
psp
[
i
],
space
=
i
)
spaces
=
tuple
(
range
(
len
(
amps
)))
a
=
ContractionOperator
(
pd
.
domain
,
spaces
[
1
:]).
adjoint
(
amps
[
0
])
for
i
in
range
(
1
,
len
(
amps
)):
a
=
a
*
(
ContractionOperator
(
pd
.
domain
,
spaces
[:
i
]
+
spaces
[(
i
+
1
):]).
adjoint
(
amps
[
i
]))
expander
=
VdotOperator
(
full
(
pd
.
domain
,
1.
)).
adjoint
Std
=
stdstd
*
ducktape
(
expander
.
domain
,
None
,
names
[
1
])
Std
=
expander
@
(
Adder
(
full
(
expander
.
domain
,
stdmean
))
@
Std
).
exp
()
if
cls
==
Field
:
A
=
pd
@
(
makeOp
(
a
)
@
Std
)
else
:
A
=
pd
@
(
Std
*
a
)
# For `vol` see comment in `CorrelatedField`
vol
=
reduce
(
mul
,
[
sp
.
scalar_dvol
**-
0.5
for
sp
in
hsp
])
return
ht
(
vol
*
A
*
ducktape
(
hsp
,
None
,
names
[
0
]))
from
..operators.value_inserter
import
ValueInserter
from
..sugar
import
from_global_data
,
from_random
,
full
,
makeDomain
def
_lognormal_moment_matching
(
mean
,
sig
,
key
):
mean
,
sig
,
key
=
float
(
mean
),
float
(
sig
),
str
(
key
)
assert
sig
>
0
logsig
=
np
.
sqrt
(
np
.
log
((
sig
/
mean
)
**
2
+
1
))
logmean
=
np
.
log
(
mean
)
-
logsig
**
2
/
2
return
_normal
(
logmean
,
logsig
,
key
).
exp
()
def
_normal
(
mean
,
sig
,
key
):
return
Adder
(
Field
.
scalar
(
mean
))
@
(
sig
*
ducktape
(
DomainTuple
.
scalar_domain
(),
None
,
key
))
class
_SlopeOperator
(
Operator
):
def
__init__
(
self
,
smooth
,
loglogavgslope
):
self
.
_domain
=
MultiDomain
.
union
(
[
smooth
.
domain
,
loglogavgslope
.
domain
])
self
.
_target
=
smooth
.
target
self
.
_smooth
=
smooth
self
.
_llas
=
loglogavgslope
logkl
=
_log_k_lengths
(
self
.
_target
[
0
])
assert
logkl
.
shape
[
0
]
==
self
.
_target
[
0
].
shape
[
0
]
-
1
logkl
-=
logkl
[
0
]
logkl
=
np
.
insert
(
logkl
,
0
,
0
)
self
.
_t
=
VdotOperator
(
from_global_data
(
self
.
_target
,
logkl
)).
adjoint
self
.
_T
=
float
(
logkl
[
-
1
])
ind
=
(
smooth
.
target
.
shape
[
0
]
-
1
,)
self
.
_extr_op
=
ValueInserter
(
smooth
.
target
,
ind
).
adjoint
def
apply
(
self
,
x
):
self
.
_check_input
(
x
)
smooth
=
self
.
_smooth
(
x
.
extract
(
self
.
_smooth
.
domain
))
res0
=
self
.
_llas
(
x
.
extract
(
self
.
_llas
.
domain
))
res1
=
self
.
_extr_op
(
smooth
)
/
self
.
_T
return
self
.
_t
(
res0
-
res1
)
+
smooth
def
_log_k_lengths
(
pspace
):
return
np
.
log
(
pspace
.
k_lengths
[
1
:])
class
_TwoLogIntegrations
(
LinearOperator
):
def
__init__
(
self
,
target
):
self
.
_target
=
makeDomain
(
target
)
self
.
_domain
=
makeDomain
(
UnstructuredDomain
((
2
,
self
.
target
.
shape
[
0
]
-
2
)))
self
.
_capability
=
self
.
TIMES
|
self
.
ADJOINT_TIMES
if
not
isinstance
(
self
.
_target
[
0
],
PowerSpace
):
raise
TypeError
logk_lengths
=
_log_k_lengths
(
self
.
_target
[
0
])
self
.
_logvol
=
logk_lengths
[
1
:]
-
logk_lengths
[:
-
1
]
def
apply
(
self
,
x
,
mode
):
self
.
_check_input
(
x
,
mode
)
if
mode
==
self
.
TIMES
:
x
=
x
.
to_global_data
()
res
=
np
.
empty
(
self
.
_target
.
shape
)
res
[
0
]
=
0
res
[
1
]
=
0
res
[
2
:]
=
np
.
cumsum
(
x
[
1
])
res
[
2
:]
=
(
res
[
2
:]
+
res
[
1
:
-
1
])
/
2
*
self
.
_logvol
+
x
[
0
]
res
[
2
:]
=
np
.
cumsum
(
res
[
2
:])
return
from_global_data
(
self
.
_target
,
res
)
else
:
x
=
x
.
to_global_data_rw
()
res
=
np
.
zeros
(
self
.
_domain
.
shape
)
x
[
2
:]
=
np
.
cumsum
(
x
[
2
:][::
-
1
])[::
-
1
]
res
[
0
]
+=
x
[
2
:]
x
[
2
:]
*=
self
.
_logvol
/
2.
res
[
1
:
-
1
]
+=
res
[
2
:]
x
[
1
]
+=
np
.
cumsum
(
res
[
2
:][::
-
1
])[::
-
1
]
return
from_global_data
(
self
.
_domain
,
res
)
class
_Normalization
(
Operator
):
def
__init__
(
self
,
domain
):
self
.
_domain
=
self
.
_target
=
makeDomain
(
domain
)
hspace
=
self
.
_domain
[
0
].
harmonic_partner
pd
=
PowerDistributor
(
hspace
,
power_space
=
self
.
_domain
[
0
])
# TODO Does not work on sphere yet
cst
=
pd
.
adjoint
(
full
(
pd
.
target
,
1.
)).
to_global_data_rw
()
cst
[
0
]
=
0
self
.
_cst
=
from_global_data
(
self
.
_domain
,
cst
)
self
.
_specsum
=
_SpecialSum
(
self
.
_domain
)
def
apply
(
self
,
x
):
self
.
_check_input
(
x
)
amp
=
x
.
exp
()
spec
=
(
2
*
x
).
exp
()
# FIXME This normalizes also the zeromode which is supposed to be left
# untouched by this operator
return
self
.
_specsum
(
self
.
_cst
*
spec
)
**
(
-
0.5
)
*
amp
class
_SpecialSum
(
EndomorphicOperator
):
def
__init__
(
self
,
domain
):
self
.
_domain
=
makeDomain
(
domain
)
self
.
_capability
=
self
.
TIMES
|
self
.
ADJOINT_TIMES
def
apply
(
self
,
x
,
mode
):
self
.
_check_input
(
x
,
mode
)
return
full
(
self
.
_tgt
(
mode
),
x
.
sum
())
class
CorrelatedFieldMaker
:
def
__init__
(
self
):
self
.
_amplitudes
=
[]
def
add_fluctuations_from_ops
(
self
,
target
,
fluctuations
,
flexibility
,
asperity
,
loglogavgslope
,
key
):
"""
fluctuations > 0
flexibility > 0
asperity > 0
loglogavgslope probably negative
"""
assert
isinstance
(
fluctuations
,
Operator
)
assert
isinstance
(
flexibility
,
Operator
)
assert
isinstance
(
asperity
,
Operator
)
assert
isinstance
(
loglogavgslope
,
Operator
)
target
=
makeDomain
(
target
)
assert
len
(
target
)
==
1
assert
isinstance
(
target
[
0
],
PowerSpace
)
twolog
=
_TwoLogIntegrations
(
target
)
dt
=
twolog
.
_logvol
sc
=
np
.
zeros
(
twolog
.
domain
.
shape
)
sc
[
0
]
=
sc
[
1
]
=
np
.
sqrt
(
dt
)
sc
=
from_global_data
(
twolog
.
domain
,
sc
)
expander
=
VdotOperator
(
sc
).
adjoint
sigmasq
=
expander
@
flexibility
dist
=
np
.
zeros
(
twolog
.
domain
.
shape
)
dist
[
0
]
+=
1.
dist
=
from_global_data
(
twolog
.
domain
,
dist
)
scale
=
VdotOperator
(
dist
).
adjoint
@
asperity
shift
=
np
.
ones
(
scale
.
target
.
shape
)
shift
[
0
]
=
dt
**
2
/
12.
shift
=
from_global_data
(
scale
.
target
,
shift
)
scale
=
sigmasq
*
(
Adder
(
shift
)
@
scale
).
sqrt
()
smooth
=
twolog
@
(
scale
*
ducktape
(
scale
.
target
,
None
,
key
))
smoothslope
=
_SlopeOperator
(
smooth
,
loglogavgslope
)
# move to tests
assert_allclose
(
smooth
(
from_random
(
'normal'
,
smooth
.
domain
)).
val
[
0
:
2
],
0
)
check_jacobian_consistency
(
smooth
,
from_random
(
'normal'
,
smooth
.
domain
))
# end move to tests
normal_ampl
=
_Normalization
(
target
)
@
smoothslope
vol
=
target
[
0
].
harmonic_partner
.
get_default_codomain
().
total_volume
arr
=
np
.
zeros
(
target
.
shape
)
arr
[
1
:]
=
vol
expander
=
VdotOperator
(
from_global_data
(
target
,
arr
)).
adjoint
mask
=
np
.
zeros
(
target
.
shape
)
mask
[
0
]
=
vol
adder
=
Adder
(
from_global_data
(
target
,
mask
))
ampl
=
adder
@
((
expander
@
fluctuations
)
*
normal_ampl
)
# Move to tests
# FIXME This test fails but it is not relevant for the final result
# assert_allclose(
# normal_ampl(from_random('normal', normal_ampl.domain)).val[0], 1)
assert_allclose
(
ampl
(
from_random
(
'normal'
,
ampl
.
domain
)).
val
[
0
],
vol
)
# End move to tests
self
.
_amplitudes
.
append
(
ampl
)
def
add_fluctuations
(
self
,
target
,
fluctuations_mean
,
fluctuations_stddev
,
flexibility_mean
,
flexibility_stddev
,
asperity_mean
,
asperity_stddev
,
loglogavgslope_mean
,
loglogavgslope_stddev
,
prefix
):
fluctuations_mean
=
float
(
fluctuations_mean
)
fluctuations_stddev
=
float
(
fluctuations_stddev
)
flexibility_mean
=
float
(
flexibility_mean
)
flexibility_stddev
=
float
(
flexibility_stddev
)
asperity_mean
=
float
(
asperity_mean
)
asperity_stddev
=
float
(
asperity_stddev
)
loglogavgslope_mean
=
float
(
loglogavgslope_mean
)
loglogavgslope_stddev
=
float
(
loglogavgslope_stddev
)
prefix
=
str
(
prefix
)
assert
fluctuations_stddev
>
0
assert
fluctuations_mean
>
0
assert
flexibility_stddev
>
0
assert
flexibility_mean
>
0
assert
asperity_stddev
>
0
assert
asperity_mean
>
0
assert
loglogavgslope_stddev
>
0
fluct
=
_lognormal_moment_matching
(
fluctuations_mean
,
fluctuations_stddev
,
prefix
+
'fluctuations'
)
flex
=
_lognormal_moment_matching
(
flexibility_mean
,
flexibility_stddev
,
prefix
+
'flexibility'
)
asp
=
_lognormal_moment_matching
(
asperity_mean
,
asperity_stddev
,
prefix
+
'asperity'
)
avgsl
=
_normal
(
loglogavgslope_mean
,
loglogavgslope_mean
,
prefix
+
'loglogavgslope'
)
self
.
add_fluctuations_from_ops
(
target
,
fluct
,
flex
,
asp
,
avgsl
,
prefix
+
'spectrum'
)
def
finalize_from_op
(
self
,
zeromode
):
raise
NotImplementedError