test_adjoint.py 12.3 KB
Newer Older
Martin Reinecke's avatar
Martin Reinecke committed
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/>.
#
Philipp Arras's avatar
Philipp Arras committed
14
# Copyright(C) 2013-2021 Max-Planck-Society
Martin Reinecke's avatar
Martin Reinecke committed
15
#
16
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
Martin Reinecke's avatar
Martin Reinecke committed
17

Philipp Arras's avatar
Philipp Arras committed
18
import nifty7 as ift
Philipp Arras's avatar
Philipp Arras committed
19
20
import numpy as np
import pytest
21

22
from ..common import list2fixture, setup_function, teardown_function
Martin Reinecke's avatar
Martin Reinecke committed
23

Philipp Arras's avatar
Philipp Arras committed
24
25
_h_RG_spaces = [ift.RGSpace(7, distances=0.2, harmonic=True),
                ift.RGSpace((12, 46), distances=(.2, .3), harmonic=True)]
Philipp Arras's avatar
Philipp Arras committed
26
_h_spaces = _h_RG_spaces + [ift.LMSpace(17)]
Philipp Arras's avatar
Philipp Arras committed
27
28
_p_RG_spaces = [ift.RGSpace(19, distances=0.7),
                ift.RGSpace((1, 2, 3, 6), distances=(0.2, 0.25, 0.34, .8))]
29
_p_spaces = _p_RG_spaces + [ift.HPSpace(17), ift.GLSpace(8, 13)]
Philipp Arras's avatar
Philipp Arras committed
30
31
_pow_spaces = [ift.PowerSpace(ift.RGSpace((17, 38), (0.99, 1340), harmonic=True)),
               ift.PowerSpace(ift.LMSpace(18), ift.PowerSpace.useful_binbounds(ift.LMSpace(18), False))]
32

Philipp Arras's avatar
Philipp Arras committed
33
34
35
pmp = pytest.mark.parametrize
dtype = list2fixture([np.float64, np.complex128])

Martin Reinecke's avatar
Martin Reinecke committed
36

Philipp Arras's avatar
Philipp Arras committed
37
38
@pmp('sp', _p_RG_spaces)
def testLOSResponse(sp, dtype):
Martin Reinecke's avatar
Martin Reinecke committed
39
40
41
42
    starts = ift.random.current_rng().standard_normal((len(sp.shape), 10))
    ends = ift.random.current_rng().standard_normal((len(sp.shape), 10))
    sigma_low = 1e-4*ift.random.current_rng().standard_normal(10)
    sigma_ups = 1e-5*ift.random.current_rng().standard_normal(10)
Philipp Arras's avatar
Philipp Arras committed
43
    op = ift.LOSResponse(sp, starts, ends, sigma_low, sigma_ups)
Philipp Arras's avatar
Philipp Arras committed
44
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
45
46
47
48


@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testOperatorCombinations(sp, dtype):
49
50
    a = ift.DiagonalOperator(ift.Field.from_random(sp, "normal", dtype=dtype))
    b = ift.DiagonalOperator(ift.Field.from_random(sp, "normal", dtype=dtype))
Philipp Arras's avatar
Philipp Arras committed
51
    op = ift.SandwichOperator.make(a, b)
Philipp Arras's avatar
Philipp Arras committed
52
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
53
    op = a(b)
Philipp Arras's avatar
Philipp Arras committed
54
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
55
    op = a + b
Philipp Arras's avatar
Philipp Arras committed
56
    ift.extra.check_linear_operator(op, dtype, dtype)
57
    op = a - b
Philipp Arras's avatar
Philipp Arras committed
58
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
59
60
61
62


def testLinearInterpolator():
    sp = ift.RGSpace((10, 8), distances=(0.1, 3.5))
Martin Reinecke's avatar
Martin Reinecke committed
63
    pos = ift.random.current_rng().random((2, 23))
Philipp Arras's avatar
Philipp Arras committed
64
65
66
    pos[0, :] *= 0.9
    pos[1, :] *= 7*3.5
    op = ift.LinearInterpolator(sp, pos)
Philipp Arras's avatar
Philipp Arras committed
67
    ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
68
69


70
71
72
@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testRealizer(sp):
    op = ift.Realizer(sp)
Philipp Arras's avatar
Philipp Arras committed
73
    ift.extra.check_linear_operator(op, np.complex128, np.float64,
Martin Reinecke's avatar
Martin Reinecke committed
74
                                only_r_linear=True)
75
76


Philipp Arras's avatar
Philipp Arras committed
77
78
79
@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testImaginizer(sp):
    op = ift.Imaginizer(sp)
Philipp Arras's avatar
Philipp Arras committed
80
    ift.extra.check_linear_operator(op, np.complex128, np.float64,
Philipp Arras's avatar
Philipp Arras committed
81
                                only_r_linear=True)
82
    loc = ift.from_random(op.domain, dtype=np.complex128)
Philipp Arras's avatar
Philipp Arras committed
83
    ift.extra.check_operator(op, loc)
Philipp Arras's avatar
Philipp Arras committed
84
85


86
87
88
@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testConjugationOperator(sp):
    op = ift.ConjugationOperator(sp)
Philipp Arras's avatar
Philipp Arras committed
89
    ift.extra.check_linear_operator(op, np.complex128, np.complex128,
Martin Reinecke's avatar
Martin Reinecke committed
90
                                only_r_linear=True)
91
92


Philipp Arras's avatar
Philipp Arras committed
93
94
@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testOperatorAdaptor(sp, dtype):
95
    op = ift.DiagonalOperator(ift.Field.from_random(sp, "normal", dtype=dtype))
Philipp Arras's avatar
Philipp Arras committed
96
97
98
99
    ift.extra.check_linear_operator(op.adjoint, dtype, dtype)
    ift.extra.check_linear_operator(op.inverse, dtype, dtype)
    ift.extra.check_linear_operator(op.inverse.adjoint, dtype, dtype)
    ift.extra.check_linear_operator(op.adjoint.inverse, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
100
101
102
103
104
105


@pmp('sp1', _h_spaces + _p_spaces + _pow_spaces)
@pmp('sp2', _h_spaces + _p_spaces + _pow_spaces)
def testNullOperator(sp1, sp2, dtype):
    op = ift.NullOperator(sp1, sp2)
Philipp Arras's avatar
Philipp Arras committed
106
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
107
108
109
    mdom1 = ift.MultiDomain.make({'a': sp1})
    mdom2 = ift.MultiDomain.make({'b': sp2})
    op = ift.NullOperator(mdom1, mdom2)
Philipp Arras's avatar
Philipp Arras committed
110
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
111
    op = ift.NullOperator(sp1, mdom2)
Philipp Arras's avatar
Philipp Arras committed
112
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
113
    op = ift.NullOperator(mdom1, sp2)
Philipp Arras's avatar
Philipp Arras committed
114
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
115
116
117
118
119


@pmp('sp', _p_RG_spaces)
def testHarmonicSmoothingOperator(sp, dtype):
    op = ift.HarmonicSmoothingOperator(sp, 0.1)
Philipp Arras's avatar
Philipp Arras committed
120
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
121
122
123
124
125
126
127
128


@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testDOFDistributor(sp, dtype):
    # TODO: Test for DomainTuple
    if sp.size < 4:
        return
    dofdex = np.arange(sp.size).reshape(sp.shape) % 3
Martin Reinecke's avatar
Martin Reinecke committed
129
    dofdex = ift.Field.from_raw(sp, dofdex)
Philipp Arras's avatar
Philipp Arras committed
130
    op = ift.DOFDistributor(dofdex)
Philipp Arras's avatar
Philipp Arras committed
131
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
132
133
134
135
136


@pmp('sp', _h_spaces)
def testPPO(sp, dtype):
    op = ift.PowerDistributor(target=sp)
Philipp Arras's avatar
Philipp Arras committed
137
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
138
139
140
    ps = ift.PowerSpace(
        sp, ift.PowerSpace.useful_binbounds(sp, logarithmic=False, nbin=3))
    op = ift.PowerDistributor(target=sp, power_space=ps)
Philipp Arras's avatar
Philipp Arras committed
141
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
142
143
144
    ps = ift.PowerSpace(
        sp, ift.PowerSpace.useful_binbounds(sp, logarithmic=True, nbin=3))
    op = ift.PowerDistributor(target=sp, power_space=ps)
Philipp Arras's avatar
Philipp Arras committed
145
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
146
147
148
149
150


@pmp('sp', _h_RG_spaces + _p_RG_spaces)
def testFFT(sp, dtype):
    op = ift.FFTOperator(sp)
Philipp Arras's avatar
Philipp Arras committed
151
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
152
    op = ift.FFTOperator(sp.get_default_codomain())
Philipp Arras's avatar
Philipp Arras committed
153
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
154
155
156
157
158


@pmp('sp', _h_RG_spaces + _p_RG_spaces)
def testHartley(sp, dtype):
    op = ift.HartleyOperator(sp)
Philipp Arras's avatar
Philipp Arras committed
159
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
160
    op = ift.HartleyOperator(sp.get_default_codomain())
Philipp Arras's avatar
Philipp Arras committed
161
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
162
163
164
165
166


@pmp('sp', _h_spaces)
def testHarmonic(sp, dtype):
    op = ift.HarmonicTransformOperator(sp)
Philipp Arras's avatar
Philipp Arras committed
167
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
168
169
170
171


@pmp('sp', _p_spaces)
def testMask(sp, dtype):
172
    f = ift.from_random(sp).val
Philipp Arras's avatar
Philipp Arras committed
173
174
    mask = np.zeros_like(f)
    mask[f > 0] = 1
Martin Reinecke's avatar
Martin Reinecke committed
175
    mask = ift.Field.from_raw(sp, mask)
Philipp Arras's avatar
Philipp Arras committed
176
    op = ift.MaskOperator(mask)
Philipp Arras's avatar
Philipp Arras committed
177
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
178
179
180
181


@pmp('sp', _h_spaces + _p_spaces)
def testDiagonal(sp, dtype):
182
    op = ift.DiagonalOperator(ift.Field.from_random(sp, dtype=dtype))
Philipp Arras's avatar
Philipp Arras committed
183
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
184
185
186
187
188


@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testGeometryRemover(sp, dtype):
    op = ift.GeometryRemover(sp)
Philipp Arras's avatar
Philipp Arras committed
189
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
190
191
192
193
194


@pmp('spaces', [0, 1, 2, 3, (0, 1), (0, 2), (0, 1, 2), (0, 2, 3), (1, 3)])
@pmp('wgt', [0, 1, 2, -1])
def testContractionOperator(spaces, wgt, dtype):
Philipp Arras's avatar
Philipp Arras committed
195
    dom = (ift.RGSpace(1), ift.RGSpace(2), ift.GLSpace(3), ift.HPSpace(2))
Philipp Arras's avatar
Philipp Arras committed
196
    op = ift.ContractionOperator(dom, spaces, wgt)
Philipp Arras's avatar
Philipp Arras committed
197
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
198
199
200


def testDomainTupleFieldInserter():
201
202
    target = ift.DomainTuple.make((ift.UnstructuredDomain([3, 2]),
                                   ift.UnstructuredDomain(7),
Philipp Arras's avatar
Philipp Arras committed
203
                                   ift.RGSpace([4, 22])))
204
    op = ift.DomainTupleFieldInserter(target, 1, (5,))
Philipp Arras's avatar
Philipp Arras committed
205
    ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
206
207
208
209
210
211


@pmp('space', [0, 2])
@pmp('factor', [1, 2, 2.7])
@pmp('central', [False, True])
def testZeroPadder(space, factor, dtype, central):
Philipp Arras's avatar
Philipp Arras committed
212
213
    dom = (ift.RGSpace(4), ift.UnstructuredDomain(5), ift.RGSpace(3, 4),
           ift.HPSpace(2))
Philipp Arras's avatar
Philipp Arras committed
214
    newshape = [int(factor*ll) for ll in dom[space].shape]
Philipp Arras's avatar
Philipp Arras committed
215
    op = ift.FieldZeroPadder(dom, newshape, space, central)
Philipp Arras's avatar
Philipp Arras committed
216
    ift.extra.check_linear_operator(op, dtype, dtype)
Philipp Arras's avatar
Philipp Arras committed
217
218


Philipp Arras's avatar
Philipp Arras committed
219
220
221
222
@pmp('args', [[ift.RGSpace((13, 52, 40)), (4, 6, 25), None],
              [ift.RGSpace((128, 128)), (45, 48), 0],
              [ift.RGSpace(13), (7,), None],
              [(ift.HPSpace(3), ift.RGSpace((12, 24), distances=0.3)), (12, 12), 1]])
Philipp Arras's avatar
Philipp Arras committed
223
224
def testRegridding(args):
    op = ift.RegriddingOperator(*args)
Philipp Arras's avatar
Philipp Arras committed
225
    ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
226

Martin Reinecke's avatar
Martin Reinecke committed
227

Philipp Arras's avatar
Fixup    
Philipp Arras committed
228
229
@pmp('fdomain', [(ift.RGSpace((2, 3, 2)), ift.RGSpace((4,), distances=(7.,))),
                 ift.HPSpace(3)])
Philipp Arras's avatar
Philipp Arras committed
230
@pmp('domain', [(ift.RGSpace(2), ift.GLSpace(10)),
Philipp Arras's avatar
Fixup    
Philipp Arras committed
231
                ift.RGSpace((4, 3), distances=(0.1, 1.))])
Philipp Arras's avatar
Philipp Arras committed
232
def testOuter(fdomain, domain):
Philipp Arras's avatar
Fixup    
Philipp Arras committed
233
    f = ift.from_random(ift.makeDomain(fdomain), 'normal')
234
    op = ift.OuterProduct(domain, f)
Philipp Arras's avatar
Philipp Arras committed
235
    ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
236
237
238


@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
Philipp Arras's avatar
Philipp Arras committed
239
240
@pmp('seed', [12, 3])
def testValueInserter(sp, seed):
Martin Reinecke's avatar
Martin Reinecke committed
241
242
243
244
245
246
247
248
    with ift.random.Context(seed):
        ind = []
        for ss in sp.shape:
            if ss == 1:
                ind.append(0)
            else:
                ind.append(int(ift.random.current_rng().integers(0, ss-1)))
        op = ift.ValueInserter(sp, ind)
Philipp Arras's avatar
Philipp Arras committed
249
        ift.extra.check_linear_operator(op)
250
251
252
253
254


@pmp('sp', _pow_spaces)
def testSlopeRemover(sp):
    op = ift.library.correlated_fields._SlopeRemover(sp)
Philipp Arras's avatar
Philipp Arras committed
255
    ift.extra.check_linear_operator(op)
256
257
258
259
260


@pmp('sp', _pow_spaces)
def testTwoLogIntegrations(sp):
    op = ift.library.correlated_fields._TwoLogIntegrations(sp)
Philipp Arras's avatar
Philipp Arras committed
261
    ift.extra.check_linear_operator(op)
262
263
264
265
266


@pmp('sp', _h_spaces + _p_spaces + _pow_spaces)
def testSpecialSum(sp):
    op = ift.library.correlated_fields._SpecialSum(sp)
Philipp Arras's avatar
Philipp Arras committed
267
    ift.extra.check_linear_operator(op)
268

Philipp Arras's avatar
Philipp Arras committed
269

Philipp Arras's avatar
Reorder    
Philipp Arras committed
270
271
272
273
274
@pmp('dofdex', [(0,), (1,), (0, 1), (1, 0)])
def testCorFldDistr(dofdex):
    tgt = ift.UnstructuredDomain(len(dofdex))
    dom = ift.UnstructuredDomain(2)
    op = ift.library.correlated_fields._Distributor(dofdex, dom, tgt)
Philipp Arras's avatar
Philipp Arras committed
275
    ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Reorder    
Philipp Arras committed
276
277


278
def metatestMatrixProductOperator(sp, mat_shape, seed, **kwargs):
Martin Reinecke's avatar
Martin Reinecke committed
279
280
281
    with ift.random.Context(seed):
        mat = ift.random.current_rng().standard_normal(mat_shape)
        op = ift.MatrixProductOperator(sp, mat, **kwargs)
Philipp Arras's avatar
Philipp Arras committed
282
        ift.extra.check_linear_operator(op)
Martin Reinecke's avatar
Martin Reinecke committed
283
284
        mat = mat + 1j*ift.random.current_rng().standard_normal(mat_shape)
        op = ift.MatrixProductOperator(sp, mat, **kwargs)
Philipp Arras's avatar
Philipp Arras committed
285
        ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
286

Philipp Arras's avatar
Philipp Arras committed
287

288
289
290
291
292
293
@pmp('sp', [ift.RGSpace(10)])
@pmp('spaces', [None, (0,)])
@pmp('seed', [12, 3])
def testMatrixProductOperator_1d(sp, spaces, seed):
    mat_shape = sp.shape * 2
    metatestMatrixProductOperator(sp, mat_shape, seed, spaces=spaces)
Philipp Arras's avatar
Philipp Arras committed
294

Philipp Arras's avatar
Philipp Arras committed
295

296
297
@pmp('sp', [ift.DomainTuple.make((ift.RGSpace((2)), ift.RGSpace((10))))])
@pmp('spaces', [(0,), (1,), (0, 1)])
298
@pmp('seed', [12, 3])
299
300
301
302
303
304
305
def testMatrixProductOperator_2d_spaces(sp, spaces, seed):
    appl_shape = []
    for sp_idx in spaces:
        appl_shape += sp[sp_idx].shape
    appl_shape = tuple(appl_shape)
    mat_shape = appl_shape * 2
    metatestMatrixProductOperator(sp, mat_shape, seed, spaces=spaces)
306

Philipp Arras's avatar
Philipp Arras committed
307

308
309
310
311
312
313
@pmp('sp', [ift.RGSpace((2, 10))])
@pmp('seed', [12, 3])
def testMatrixProductOperator_2d_flatten(sp, seed):
    appl_shape = (ift.utilities.my_product(sp.shape),)
    mat_shape = appl_shape * 2
    metatestMatrixProductOperator(sp, mat_shape, seed, flatten=True)
314

Philipp Arras's avatar
Philipp Arras committed
315

Philipp Arras's avatar
Philipp Arras committed
316
317
@pmp('seed', [12, 3])
def testPartialExtractor(seed):
Martin Reinecke's avatar
Martin Reinecke committed
318
319
320
321
322
323
324
    with ift.random.Context(seed):
        tgt = {'a': ift.RGSpace(1), 'b': ift.RGSpace(2)}
        dom = tgt.copy()
        dom['c'] = ift.RGSpace(3)
        dom = ift.MultiDomain.make(dom)
        tgt = ift.MultiDomain.make(tgt)
        op = ift.PartialExtractor(dom, tgt)
Philipp Arras's avatar
Philipp Arras committed
325
        ift.extra.check_linear_operator(op)
Philipp Arras's avatar
Philipp Arras committed
326

Philipp Arras's avatar
Philipp Arras committed
327

Philipp Arras's avatar
Philipp Arras committed
328
329
330
331
@pmp('seed', [12, 3])
def testSlowFieldAdapter(seed):
    dom = {'a': ift.RGSpace(1), 'b': ift.RGSpace(2)}
    op = ift.operators.simple_linear_operators._SlowFieldAdapter(dom, 'a')
Philipp Arras's avatar
Philipp Arras committed
332
    ift.extra.check_linear_operator(op)
Jakob Knollmüller's avatar
Jakob Knollmüller committed
333
334
335
336
337
338
339
340
341

@pmp('seed', [12, 3])
def testDiagonalExtractor(seed):
    N = 42
    square_space = ift.RGSpace([N,N])
    op = ift.library.variational_models.DiagonalSelector(square_space)
    ift.extra.check_linear_operator(op)

@pmp('seed', [12, 3])
Philipp Arras's avatar
Philipp Arras committed
342
343
344
@pmp("N", [10, 17])
def testLowerTriangularInserter(seed, N):
    square_space = ift.RGSpace([N, N])
Jakob Knollmüller's avatar
Jakob Knollmüller committed
345
346
347
348
349
350
    op = ift.library.variational_models.LowerTriangularInserter(square_space)
    ift.extra.check_linear_operator(op)

@pmp('seed', [12, 3])
def test_Multifield2Vector(seed):
    dom = {'a': ift.RGSpace(1), 'b': ift.RGSpace(2)}
Jakob Knollmüller's avatar
debug    
Jakob Knollmüller committed
351
    dom = ift.MultiDomain.make(dom)
Jakob Knollmüller's avatar
Jakob Knollmüller committed
352
353
    op = ift.Multifield2Vector(dom)
    ift.extra.check_linear_operator(op)