getting_started_3.py 4.43 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# 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-2018 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.

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


def get_random_LOS(n_los):
24 25
    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
26 27
    return starts, ends

28

Jakob Knollmueller's avatar
Jakob Knollmueller committed
29
if __name__ == '__main__':
Philipp Arras's avatar
Philipp Arras committed
30
    # FIXME description of the tutorial
31
    np.random.seed(42)
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
Martin Reinecke's avatar
fixes  
Martin Reinecke committed
35
    A, amplitude_internals = ift.make_amplitude_model(
36
        position_space, 16, 1, 10, -4., 1, 0., 1.)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
37 38 39 40 41 42

    # Building the model for a correlated signal
    harmonic_space = position_space.get_default_codomain()
    ht = ift.HarmonicTransformOperator(harmonic_space, position_space)
    power_space = A.value.domain[0]
    power_distributor = ift.PowerDistributor(harmonic_space, power_space)
Martin Reinecke's avatar
Martin Reinecke committed
43 44
    position = ift.MultiField.from_dict(
        {'xi': ift.Field.from_random('normal', harmonic_space)})
Jakob Knollmueller's avatar
Jakob Knollmueller committed
45 46 47 48 49

    xi = ift.Variable(position)['xi']
    Amp = power_distributor(A)
    correlated_field_h = Amp * xi
    correlated_field = ht(correlated_field_h)
50
    # alternatively to the block above one can do:
Martin Reinecke's avatar
fixes  
Martin Reinecke committed
51
    # correlated_field,_ = ift.make_correlated_field(position_space, A)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
52 53 54

    # apply some nonlinearity
    signal = ift.PointwisePositiveTanh(correlated_field)
Martin Reinecke's avatar
Martin Reinecke committed
55

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

    # generate mock data
    MOCK_POSITION = ift.from_random('normal', signal.position.domain)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
69
    data = signal_response.at(MOCK_POSITION).value + N.draw_sample()
Jakob Knollmueller's avatar
Jakob Knollmueller committed
70 71 72 73 74

    # set up model likelihood
    likelihood = ift.GaussianEnergy(signal_response, mean=data, covariance=N)

    # set up minimization and inversion schemes
Jakob Knollmueller's avatar
Jakob Knollmueller committed
75 76
    ic_cg = ift.GradientNormController(iteration_limit=10)
    ic_sampling = ift.GradientNormController(iteration_limit=100)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
77 78
    ic_newton = ift.GradientNormController(name='Newton', iteration_limit=100)
    minimizer = ift.RelaxedNewton(ic_newton)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
79

Jakob Knollmueller's avatar
Jakob Knollmueller committed
80
    # build model Hamiltonian
Martin Reinecke's avatar
Martin Reinecke committed
81
    H = ift.Hamiltonian(likelihood, ic_sampling)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
82

83
    INITIAL_POSITION = ift.from_random('normal', H.position.domain)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
84
    position = INITIAL_POSITION
Jakob Knollmueller's avatar
Jakob Knollmueller committed
85

Martin Reinecke's avatar
Martin Reinecke committed
86 87 88 89
    ift.plot(signal.at(MOCK_POSITION).value, title='ground truth')
    ift.plot(R.adjoint_times(data), title='data')
    ift.plot([A.at(MOCK_POSITION).value], title='power')
    ift.plot_finish(nx=3, xsize=16, ysize=5, title="setup", name="setup.png")
Jakob Knollmueller's avatar
Jakob Knollmueller committed
90

Jakob Knollmueller's avatar
Jakob Knollmueller committed
91
    # number of samples used to estimate the KL
92
    N_samples = 20
Martin Reinecke's avatar
Martin Reinecke committed
93
    for i in range(2):
Jakob Knollmueller's avatar
Jakob Knollmueller committed
94
        H = H.at(position)
Martin Reinecke's avatar
Martin Reinecke committed
95
        samples = [H.metric.draw_sample(from_inverse=True)
96
                   for _ in range(N_samples)]
Jakob Knollmueller's avatar
Jakob Knollmueller committed
97

Martin Reinecke's avatar
Martin Reinecke committed
98
        KL = ift.SampledKullbachLeiblerDivergence(H, samples)
99
        KL = KL.make_invertible(ic_cg)
Jakob Knollmueller's avatar
Jakob Knollmueller committed
100 101 102
        KL, convergence = minimizer(KL)
        position = KL.position

Martin Reinecke's avatar
Martin Reinecke committed
103
        ift.plot(signal.at(position).value, title="reconstruction")
Jakob Knollmueller's avatar
Jakob Knollmueller committed
104

105
        ift.plot([A.at(position).value, A.at(MOCK_POSITION).value],
Martin Reinecke's avatar
Martin Reinecke committed
106 107
                 title="power")
        ift.plot_finish(nx=2, xsize=12, ysize=6, title="loop", name="loop.png")
Jakob Knollmueller's avatar
Jakob Knollmueller committed
108

Martin Reinecke's avatar
Martin Reinecke committed
109
    sc = ift.StatCalculator()
Jakob Knollmueller's avatar
Jakob Knollmueller committed
110
    for sample in samples:
Martin Reinecke's avatar
Martin Reinecke committed
111
        sc.add(signal.at(sample+position).value)
Martin Reinecke's avatar
Martin Reinecke committed
112 113
    ift.plot(sc.mean, title="mean")
    ift.plot(ift.sqrt(sc.var), title="std deviation")
Martin Reinecke's avatar
Martin Reinecke committed
114 115

    powers = [A.at(s+position).value for s in samples]
116
    ift.plot([A.at(position).value, A.at(MOCK_POSITION).value]+powers,
Martin Reinecke's avatar
Martin Reinecke committed
117 118
             title="power")
    ift.plot_finish(nx=3, xsize=16, ysize=5, title="results", name="results.png")