getting_started_3.py 4.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
# 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/>.
#
14
# Copyright(C) 2013-2019 Max-Planck-Society
15
#
16
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
17

Jakob Knollmueller's avatar
Jakob Knollmueller committed
18
19
20
21
22
import nifty5 as ift
import numpy as np


def get_random_LOS(n_los):
23
24
    starts = list(np.random.uniform(0, 1, (n_los, 2)).T)
    ends = list(np.random.uniform(0, 1, (n_los, 2)).T)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
25
26
    return starts, ends

Martin Reinecke's avatar
cleanup    
Martin Reinecke committed
27

Jakob Knollmueller's avatar
Jakob Knollmueller committed
28
if __name__ == '__main__':
Philipp Arras's avatar
Philipp Arras committed
29
    # FIXME description of the tutorial
30
    np.random.seed(42)
Philipp Arras's avatar
Philipp Arras committed
31
    np.seterr(all='raise')
32
    position_space = ift.RGSpace([128, 128])
Jakob Knollmueller's avatar
Jakob Knollmueller committed
33

Jakob Knollmueller's avatar
Jakob Knollmueller committed
34
    # Setting up an amplitude model
35
    A = ift.AmplitudeModel(position_space, 64, 3, 0.4, -4., 1, 1., 1.)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
36
37
38
39

    # Building the model for a correlated signal
    harmonic_space = position_space.get_default_codomain()
    ht = ift.HarmonicTransformOperator(harmonic_space, position_space)
Martin Reinecke's avatar
cleanup    
Martin Reinecke committed
40
    power_space = A.target[0]
Jakob Knollmueller's avatar
Jakob Knollmueller committed
41
42
    power_distributor = ift.PowerDistributor(harmonic_space, power_space)

43
    vol = harmonic_space.scalar_dvol
Martin Reinecke's avatar
Martin Reinecke committed
44
    vol = ift.ScalingOperator(vol**(-0.5), harmonic_space)
Martin Reinecke's avatar
Martin Reinecke committed
45
46
    correlated_field = ht(
        vol(power_distributor(A))*ift.ducktape(harmonic_space, None, 'xi'))
47
    # alternatively to the block above one can do:
48
    #correlated_field = ift.CorrelatedField(position_space, A)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
49
50

    # apply some nonlinearity
Jakob Knollmueller's avatar
Jakob Knollmueller committed
51
    signal = ift.sigmoid(correlated_field)
Martin Reinecke's avatar
Martin Reinecke committed
52

Jakob Knollmueller's avatar
Jakob Knollmueller committed
53
    # Building the Line of Sight response
54
    LOS_starts, LOS_ends = get_random_LOS(100)
Philipp Arras's avatar
Philipp Arras committed
55
    R = ift.LOSResponse(position_space, starts=LOS_starts, ends=LOS_ends)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
56
    # build signal response model and model likelihood
Martin Reinecke's avatar
Martin Reinecke committed
57
    signal_response = R(signal)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
58
59
    # specify noise
    data_space = R.target
Jakob Knollmueller's avatar
Jakob Knollmueller committed
60
    noise = .001
61
    N = ift.ScalingOperator(noise, data_space)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
62
63

    # generate mock data
Philipp Arras's avatar
Philipp Arras committed
64
    MOCK_POSITION = ift.from_random('normal', signal_response.domain)
Martin Reinecke's avatar
cleanup    
Martin Reinecke committed
65
    data = signal_response(MOCK_POSITION) + N.draw_sample()
Jakob Knollmueller's avatar
Jakob Knollmueller committed
66
67

    # set up model likelihood
Philipp Arras's avatar
Philipp Arras committed
68
    likelihood = ift.GaussianEnergy(mean=data, covariance=N)(signal_response)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
69
70

    # set up minimization and inversion schemes
Jakob Knollmueller's avatar
Jakob Knollmueller committed
71
    ic_sampling = ift.GradientNormController(iteration_limit=100)
Martin Reinecke's avatar
Martin Reinecke committed
72
    ic_newton = ift.GradInfNormController(
73
        name='Newton', tol=1e-7, iteration_limit=35)
74
    minimizer = ift.NewtonCG(ic_newton)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
75

Jakob Knollmueller's avatar
Jakob Knollmueller committed
76
    # build model Hamiltonian
Martin Reinecke's avatar
Martin Reinecke committed
77
    H = ift.Hamiltonian(likelihood, ic_sampling)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
78

79
    INITIAL_POSITION = ift.MultiField.full(H.domain, 0.)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
80
    position = INITIAL_POSITION
Jakob Knollmueller's avatar
Jakob Knollmueller committed
81

82
    plot = ift.Plot()
Martin Reinecke's avatar
merge    
Martin Reinecke committed
83
84
    plot.add(signal(MOCK_POSITION), title='Ground Truth')
    plot.add(R.adjoint_times(data), title='Data')
Philipp Arras's avatar
Philipp Arras committed
85
    plot.add([A.force(MOCK_POSITION)], title='Power Spectrum')
Martin Reinecke's avatar
merge    
Martin Reinecke committed
86
    plot.output(ny=1, nx=3, xsize=24, ysize=6, name="setup.png")
Jakob Knollmueller's avatar
Jakob Knollmueller committed
87

Jakob Knollmueller's avatar
Jakob Knollmueller committed
88
    # number of samples used to estimate the KL
89
    N_samples = 20
90
    for i in range(5):
Martin Reinecke's avatar
Martin Reinecke committed
91
        KL = ift.KL_Energy(position, H, N_samples)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
92
93
94
        KL, convergence = minimizer(KL)
        position = KL.position

95
        plot = ift.Plot()
Martin Reinecke's avatar
merge    
Martin Reinecke committed
96
        plot.add(signal(KL.position), title="reconstruction")
Philipp Arras's avatar
Philipp Arras committed
97
        plot.add([A.force(KL.position), A.force(MOCK_POSITION)], title="power")
Lukas Platz's avatar
Lukas Platz committed
98
        plot.output(ny=1, ysize=6, xsize=16, name="loop-{:02}.png".format(i))
Jakob Knollmueller's avatar
Jakob Knollmueller committed
99

Philipp Arras's avatar
Philipp Arras committed
100
    KL = ift.KL_Energy(position, H, N_samples)
101
    plot = ift.Plot()
Martin Reinecke's avatar
Martin Reinecke committed
102
    sc = ift.StatCalculator()
103
    for sample in KL.samples:
Philipp Arras's avatar
Philipp Arras committed
104
        sc.add(signal(sample + KL.position))
Martin Reinecke's avatar
merge    
Martin Reinecke committed
105
106
    plot.add(sc.mean, title="Posterior Mean")
    plot.add(ift.sqrt(sc.var), title="Posterior Standard Deviation")
Martin Reinecke's avatar
Martin Reinecke committed
107

Philipp Arras's avatar
Philipp Arras committed
108
    powers = [A.force(s + KL.position) for s in KL.samples]
Martin Reinecke's avatar
merge    
Martin Reinecke committed
109
    plot.add(
Lukas Platz's avatar
Lukas Platz committed
110
111
112
        powers + [A.force(KL.position), A.force(MOCK_POSITION)],
        title="Sampled Posterior Power Spectrum",
        linewidth=[1.]*len(powers) + [3., 3.])
Martin Reinecke's avatar
merge    
Martin Reinecke committed
113
    plot.output(ny=1, nx=3, xsize=24, ysize=6, name="results.png")