test_jacobian.py 6.51 KB
Newer Older
Philipp Arras's avatar
Philipp Arras committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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 numpy as np
import pytest

Martin Reinecke's avatar
5->6    
Martin Reinecke committed
21
import nifty6 as ift
Philipp Arras's avatar
Philipp Arras committed
22

23
from ..common import list2fixture, setup_function, teardown_function
Philipp Arras's avatar
Philipp Arras committed
24
25
26
27
28
29
30

pmp = pytest.mark.parametrize
space = list2fixture([
    ift.GLSpace(15),
    ift.RGSpace(64, distances=.789),
    ift.RGSpace([32, 32], distances=.789)
])
Philipp Arras's avatar
Philipp Arras committed
31
32
33
34
35
_h_RG_spaces = [
    ift.RGSpace(7, distances=0.2, harmonic=True),
    ift.RGSpace((12, 46), distances=(.2, .3), harmonic=True)
]
_h_spaces = _h_RG_spaces + [ift.LMSpace(17)]
Philipp Arras's avatar
Philipp Arras committed
36
37
38
39
space1 = space
seed = list2fixture([4, 78, 23])


Philipp Arras's avatar
Philipp Arras committed
40
def testBasics(space, seed):
Martin Reinecke's avatar
Martin Reinecke committed
41
    ift.random.push_sseq_from_seed(seed)
42
    S = ift.ScalingOperator(space, 1.)
Philipp Arras's avatar
Philipp Arras committed
43
    s = S.draw_sample()
Philipp Arras's avatar
Philipp Arras committed
44
    var = ift.Linearization.make_var(s)
45
    model = ift.ScalingOperator(var.target, 6.)
Martin Reinecke's avatar
Martin Reinecke committed
46
    ift.extra.check_jacobian_consistency(model, var.val)
Martin Reinecke's avatar
Martin Reinecke committed
47
    ift.random.pop_sseq()
Philipp Arras's avatar
Philipp Arras committed
48
49
50
51
52


@pmp('type1', ['Variable', 'Constant'])
@pmp('type2', ['Variable'])
def testBinary(type1, type2, space, seed):
Martin Reinecke's avatar
Martin Reinecke committed
53
    ift.random.push_sseq_from_seed(seed)
Philipp Arras's avatar
Philipp Arras committed
54
55
56
    dom1 = ift.MultiDomain.make({'s1': space})
    dom2 = ift.MultiDomain.make({'s2': space})
    dom = ift.MultiDomain.union((dom1, dom2))
57
58
    select_s1 = ift.ducktape(None, dom1, "s1")
    select_s2 = ift.ducktape(None, dom2, "s2")
Philipp Arras's avatar
Philipp Arras committed
59
60
    model = select_s1*select_s2
    pos = ift.from_random("normal", dom)
Martin Reinecke's avatar
Martin Reinecke committed
61
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Philipp Arras's avatar
Philipp Arras committed
62
63
    model = select_s1 + select_s2
    pos = ift.from_random("normal", dom)
Martin Reinecke's avatar
Martin Reinecke committed
64
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Philipp Arras's avatar
Philipp Arras committed
65
66
    model = select_s1.scale(3.)
    pos = ift.from_random("normal", dom1)
Martin Reinecke's avatar
Martin Reinecke committed
67
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
68
    model = ift.ScalingOperator(space, 2.456)(select_s1*select_s2)
Philipp Arras's avatar
Philipp Arras committed
69
    pos = ift.from_random("normal", dom)
Martin Reinecke's avatar
Martin Reinecke committed
70
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
71
    model = ift.sigmoid(2.456*(select_s1*select_s2))
Philipp Arras's avatar
Philipp Arras committed
72
    pos = ift.from_random("normal", dom)
Martin Reinecke's avatar
Martin Reinecke committed
73
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Philipp Arras's avatar
Philipp Arras committed
74
75
    pos = ift.from_random("normal", dom)
    model = ift.OuterProduct(pos['s1'], ift.makeDomain(space))
Martin Reinecke's avatar
Martin Reinecke committed
76
    ift.extra.check_jacobian_consistency(model, pos['s2'], ntries=20)
Martin Reinecke's avatar
Martin Reinecke committed
77
    model = select_s1**2
78
    pos = ift.from_random("normal", dom1)
Martin Reinecke's avatar
Martin Reinecke committed
79
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Martin Reinecke's avatar
Martin Reinecke committed
80
    model = select_s1.clip(-1, 1)
81
    pos = ift.from_random("normal", dom1)
82
83
84
85
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
    f = ift.from_random("normal", space)
    model = select_s1.clip(f-0.1, f+1.)
    pos = ift.from_random("normal", dom1)
Martin Reinecke's avatar
Martin Reinecke committed
86
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Philipp Arras's avatar
Philipp Arras committed
87
88
89
    if isinstance(space, ift.RGSpace):
        model = ift.FFTOperator(space)(select_s1*select_s2)
        pos = ift.from_random("normal", dom)
Martin Reinecke's avatar
Martin Reinecke committed
90
        ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Martin Reinecke's avatar
Martin Reinecke committed
91
    ift.random.pop_sseq()
Philipp Arras's avatar
Philipp Arras committed
92
93


Rouven Lemmerz's avatar
Rouven Lemmerz committed
94
def testSpecialDistributionOps(space, seed):
Martin Reinecke's avatar
Martin Reinecke committed
95
    ift.random.push_sseq_from_seed(seed)
96
    S = ift.ScalingOperator(space, 1.)
Philipp Arras's avatar
Philipp Arras committed
97
98
99
    pos = S.draw_sample()
    alpha = 1.5
    q = 0.73
Philipp Arras's avatar
Fixups    
Philipp Arras committed
100
    model = ift.InverseGammaOperator(space, alpha, q)
Rouven Lemmerz's avatar
Rouven Lemmerz committed
101
102
103
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
    model = ift.UniformOperator(space, alpha, q)
    ift.extra.check_jacobian_consistency(model, pos, ntries=20)
Martin Reinecke's avatar
Martin Reinecke committed
104
    ift.random.pop_sseq()
Martin Reinecke's avatar
Martin Reinecke committed
105

106

Philipp Arras's avatar
Philipp Arras committed
107
108
@pmp('neg', [True, False])
def testAdder(space, seed, neg):
Martin Reinecke's avatar
Martin Reinecke committed
109
    ift.random.push_sseq_from_seed(seed)
Philipp Arras's avatar
Philipp Arras committed
110
111
112
113
114
115
116
    S = ift.ScalingOperator(space, 1.)
    f = S.draw_sample()
    f1 = S.draw_sample()
    op = ift.Adder(f1, neg)
    ift.extra.check_jacobian_consistency(op, f)
    op = ift.Adder(f1.val.ravel()[0], neg=neg, domain=space)
    ift.extra.check_jacobian_consistency(op, f)
Martin Reinecke's avatar
Martin Reinecke committed
117
    ift.random.pop_sseq()
Philipp Arras's avatar
Philipp Arras committed
118
119
120
121
122


@pmp('target', [ift.RGSpace(64, distances=.789, harmonic=True),
                ift.RGSpace([32, 32], distances=.789, harmonic=True),
                ift.RGSpace([32, 32, 8], distances=.789, harmonic=True)])
Martin Reinecke's avatar
Martin Reinecke committed
123
124
@pmp('causal', [True, False])
@pmp('minimum_phase', [True, False])
Philipp Frank's avatar
Philipp Frank committed
125
def testDynamicModel(target, causal, minimum_phase, seed):
Martin Reinecke's avatar
Martin Reinecke committed
126
    ift.random.push_sseq_from_seed(seed)
Philipp Frank's avatar
Philipp Frank committed
127
128
129
130
131
132
133
134
135
136
    dct = {
            'target': target,
            'harmonic_padding': None,
            'sm_s0': 3.,
            'sm_x0': 1.,
            'key': 'f',
            'causal': causal,
            'minimum_phase': minimum_phase
            }
    model, _ = ift.dynamic_operator(**dct)
137
    S = ift.ScalingOperator(model.domain, 1.)
Martin Reinecke's avatar
Martin Reinecke committed
138
139
    pos = S.draw_sample()
    # FIXME I dont know why smaller tol fails for 3D example
Martin Reinecke's avatar
Martin Reinecke committed
140
    ift.extra.check_jacobian_consistency(model, pos, tol=1e-5, ntries=20)
Philipp Frank's avatar
Philipp Frank committed
141
    if len(target.shape) > 1:
142
        dct = {
Philipp Frank's avatar
Philipp Frank committed
143
            'target': target,
144
145
146
147
148
149
150
151
152
153
            'harmonic_padding': None,
            'sm_s0': 3.,
            'sm_x0': 1.,
            'key': 'f',
            'lightcone_key': 'c',
            'sigc': 1.,
            'quant': 5,
            'causal': causal,
            'minimum_phase': minimum_phase
        }
Philipp Frank's avatar
Philipp Frank committed
154
155
156
        dct['lightcone_key'] = 'c'
        dct['sigc'] = 1.
        dct['quant'] = 5
157
        model, _ = ift.dynamic_lightcone_operator(**dct)
158
        S = ift.ScalingOperator(model.domain, 1.)
Martin Reinecke's avatar
Martin Reinecke committed
159
160
        pos = S.draw_sample()
        # FIXME I dont know why smaller tol fails for 3D example
Martin Reinecke's avatar
Martin Reinecke committed
161
        ift.extra.check_jacobian_consistency(
162
            model, pos, tol=1e-5, ntries=20)
Martin Reinecke's avatar
Martin Reinecke committed
163
    ift.random.pop_sseq()
Philipp Arras's avatar
Philipp Arras committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180


@pmp('h_space', _h_spaces)
@pmp('specialbinbounds', [True, False])
@pmp('logarithmic', [True, False])
@pmp('nbin', [3, None])
def testNormalization(h_space, specialbinbounds, logarithmic, nbin):
    if not specialbinbounds and (not logarithmic or nbin is not None):
        return
    if specialbinbounds:
        binbounds = ift.PowerSpace.useful_binbounds(h_space, logarithmic, nbin)
    else:
        binbounds = None
    dom = ift.PowerSpace(h_space, binbounds)
    op = ift.library.correlated_fields._Normalization(dom)
    pos = 0.1*ift.from_random('normal', op.domain)
    ift.extra.check_jacobian_consistency(op, pos)