Commit d013a4c9 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

Merge branch 'NIFTy_5' into mr_docs

parents fbde69fd 972e8bc7
......@@ -10,6 +10,7 @@ setup.cfg
.document
.svn/
*.csv
.pytest_cache/
# from https://github.com/github/gitignore/blob/master/Python.gitignore
......
......@@ -9,7 +9,7 @@ RUN apt-get update && apt-get install -y \
# Documentation build dependencies
python3-sphinx python3-sphinx-rtd-theme python3-numpydoc \
# Testing dependencies
python3-coverage python3-parameterized python3-pytest python3-pytest-cov \
python3-coverage python3-pytest python3-pytest-cov \
# Optional NIFTy dependencies
openmpi-bin libopenmpi-dev python3-mpi4py \
# Packages needed for NIFTy
......
......@@ -15,20 +15,12 @@
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
from builtins import str
import pytest
import numpy as np
from parameterized import parameterized
np.seterr(all='raise', under='ignore')
def list2fixture(lst):
@pytest.fixture(params=lst)
def myfixture(request):
return request.param
def _custom_name_func(testcase_func, param_num, param):
return "{}_{}".format(
testcase_func.__name__,
parameterized.to_safe_name("_".join(str(x) for x in param.args)),
)
def expand(*args, **kwargs):
return parameterized.expand(*args, func=_custom_name_func, **kwargs)
return myfixture
# 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 unittest
from itertools import product
from test.common import expand
import nifty5 as ift
import numpy as np
class Energy_Tests(unittest.TestCase):
def make_operator(self, **kwargs):
np.random.seed(kwargs['seed'])
S = ift.ScalingOperator(1., kwargs['space'])
s = S.draw_sample()
return ift.MultiField.from_dict({kwargs['space_key']: s})
@expand(product(
[ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)],
[4, 78, 23]
))
def testGaussian(self, space, seed):
op = self.make_operator(
space_key='s1', space=space, seed=seed)['s1']
energy = ift.GaussianEnergy(domain=space)
ift.extra.check_value_gradient_consistency(energy, op)
# @expand(product(
# [ift.GLSpace(15),
# ift.RGSpace(64, distances=.789),
# ift.RGSpace([32, 32], distances=.789)],
# [4, 78, 23]
# ))
# def testQuadratic(self, type1, space, seed):
# np.random.seed(seed)
# S = ift.ScalingOperator(1., space)
# s = [S.draw_sample() for _ in range(3)]
# energy = ift.QuadraticEnergy(s[0], ift.makeOp(s[1]), s[2])
# ift.extra.check_value_gradient_consistency(energy)
@expand(
product([
ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)
], [4, 78, 23]))
def testInverseGammaLikelihood(self, space, seed):
op = self.make_operator(space_key='s1', space=space, seed=seed)['s1']
op = op.exp()
d = np.random.normal(10, size=space.shape)**2
d = ift.Field.from_global_data(space, d)
energy = ift.InverseGammaLikelihood(d)
ift.extra.check_value_gradient_consistency(energy, op, tol=1e-7)
@expand(product(
[ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)],
[4, 78, 23]
))
def testPoissonian(self, space, seed):
op = self.make_operator(
space_key='s1', space=space, seed=seed)['s1']
op = op.exp()
d = np.random.poisson(120, size=space.shape)
d = ift.Field.from_global_data(space, d)
energy = ift.PoissonianEnergy(d)
ift.extra.check_value_gradient_consistency(energy, op, tol=1e-7)
@expand(product(
[ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)],
[4, 78, 23]
))
def testHamiltonian_and_KL(self, space, seed):
op = self.make_operator(
space_key='s1', space=space, seed=seed)['s1']
op = op.exp()
lh = ift.GaussianEnergy(domain=space)
hamiltonian = ift.Hamiltonian(lh)
ift.extra.check_value_gradient_consistency(hamiltonian, op)
S = ift.ScalingOperator(1., space)
samps = [S.draw_sample() for i in range(3)]
kl = ift.SampledKullbachLeiblerDivergence(hamiltonian, samps)
ift.extra.check_value_gradient_consistency(kl, op)
@expand(product(
[ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)],
[4, 78, 23]
))
def testBernoulli(self, space, seed):
op = self.make_operator(
space_key='s1', space=space, seed=seed)['s1']
op = op.sigmoid()
d = np.random.binomial(1, 0.1, size=space.shape)
d = ift.Field.from_global_data(space, d)
energy = ift.BernoulliEnergy(d)
ift.extra.check_value_gradient_consistency(energy, op, tol=1e-6)
# 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
import nifty5 as ift
from itertools import product
# Currently it is not possible to parametrize fixtures. But this will
# hopefully be fixed in the future.
# https://docs.pytest.org/en/latest/proposals/parametrize_with_fixtures.html
SPACES = [
ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)
]
SEEDS = [4, 78, 23]
PARAMS = product(SEEDS, SPACES)
@pytest.fixture(params=PARAMS)
def field(request):
np.random.seed(request.param[0])
S = ift.ScalingOperator(1., request.param[1])
s = S.draw_sample()
return ift.MultiField.from_dict({'s1': s})['s1']
def test_gaussian(field):
energy = ift.GaussianEnergy(domain=field.domain)
ift.extra.check_value_gradient_consistency(energy, field)
def test_inverse_gamma(field):
field = field.exp()
space = field.domain
d = np.random.normal(10, size=space.shape)**2
d = ift.Field.from_global_data(space, d)
energy = ift.InverseGammaLikelihood(d)
ift.extra.check_value_gradient_consistency(energy, field, tol=1e-7)
def testPoissonian(field):
field = field.exp()
space = field.domain
d = np.random.poisson(120, size=space.shape)
d = ift.Field.from_global_data(space, d)
energy = ift.PoissonianEnergy(d)
ift.extra.check_value_gradient_consistency(energy, field, tol=1e-7)
def test_hamiltonian_and_KL(field):
field = field.exp()
space = field.domain
lh = ift.GaussianEnergy(domain=space)
hamiltonian = ift.Hamiltonian(lh)
ift.extra.check_value_gradient_consistency(hamiltonian, field)
S = ift.ScalingOperator(1., space)
samps = [S.draw_sample() for i in range(3)]
kl = ift.SampledKullbachLeiblerDivergence(hamiltonian, samps)
ift.extra.check_value_gradient_consistency(kl, field)
def test_bernoulli(field):
field = field.sigmoid()
space = field.domain
d = np.random.binomial(1, 0.1, size=space.shape)
d = ift.Field.from_global_data(space, d)
energy = ift.BernoulliEnergy(d)
ift.extra.check_value_gradient_consistency(energy, field, tol=1e-6)
......@@ -15,25 +15,22 @@
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
import unittest
from itertools import product
from test.common import expand
import nifty5 as ift
import numpy as np
import pytest
from numpy.testing import assert_allclose, assert_equal, assert_raises
import nifty5 as ift
pmp = pytest.mark.parametrize
SPACES = [ift.RGSpace((4,)), ift.RGSpace((5))]
SPACE_COMBINATIONS = [(), SPACES[0], SPACES[1], SPACES]
class Test_Interface(unittest.TestCase):
@expand(product(SPACE_COMBINATIONS,
[['domain', ift.DomainTuple],
['val', ift.dobj.data_object],
['shape', tuple],
['size', (np.int, np.int64)]]))
def test_return_types(self, domain, attribute_desired_type):
@pmp('domain', SPACE_COMBINATIONS)
@pmp('attribute_desired_type',
[['domain', ift.DomainTuple], ['val', ift.dobj.data_object],
['shape', tuple], ['size', (np.int, np.int64)]])
def test_return_types(domain, attribute_desired_type):
attribute = attribute_desired_type[0]
desired_type = attribute_desired_type[1]
f = ift.Field.full(domain, 1.)
......@@ -41,19 +38,19 @@ class Test_Interface(unittest.TestCase):
def _spec1(k):
return 42/(1.+k)**2
return 42/(1. + k)**2
def _spec2(k):
return 42/(1.+k)**3
return 42/(1. + k)**3
class Test_Functionality(unittest.TestCase):
@expand(product([ift.RGSpace((8,), harmonic=True),
ift.RGSpace((8, 8), harmonic=True, distances=0.123)],
[ift.RGSpace((8,), harmonic=True),
ift.LMSpace(12)]))
def test_power_synthesize_analyze(self, space1, space2):
@pmp('space1', [
ift.RGSpace((8,), harmonic=True),
ift.RGSpace((8, 8), harmonic=True, distances=0.123)
])
@pmp('space2', [ift.RGSpace((8,), harmonic=True), ift.LMSpace(12)])
def test_power_synthesize_analyze(space1, space2):
np.random.seed(11)
p1 = ift.PowerSpace(space1)
......@@ -73,19 +70,20 @@ class Test_Functionality(unittest.TestCase):
for ii in range(samples):
sk = opfull.draw_sample()
sp = ift.power_analyze(sk, spaces=(0, 1),
keep_phase_information=False)
sp = ift.power_analyze(sk, spaces=(0, 1), keep_phase_information=False)
sc1.add(sp.sum(spaces=1)/fp2.sum())
sc2.add(sp.sum(spaces=0)/fp1.sum())
assert_allclose(sc1.mean.local_data, fp1.local_data, rtol=0.2)
assert_allclose(sc2.mean.local_data, fp2.local_data, rtol=0.2)
@expand(product([ift.RGSpace((8,), harmonic=True),
ift.RGSpace((8, 8), harmonic=True, distances=0.123)],
[ift.RGSpace((8,), harmonic=True),
ift.LMSpace(12)]))
def test_DiagonalOperator_power_analyze2(self, space1, space2):
@pmp('space1', [
ift.RGSpace((8,), harmonic=True),
ift.RGSpace((8, 8), harmonic=True, distances=0.123)
])
@pmp('space2', [ift.RGSpace((8,), harmonic=True), ift.LMSpace(12)])
def test_DiagonalOperator_power_analyze2(space1, space2):
np.random.seed(11)
fp1 = ift.PS_field(ift.PowerSpace(space1), _spec1)
......@@ -101,18 +99,20 @@ class Test_Functionality(unittest.TestCase):
for ii in range(samples):
sk = S_full.draw_sample()
sp = ift.power_analyze(sk, spaces=(0, 1),
keep_phase_information=False)
sp = ift.power_analyze(sk, spaces=(0, 1), keep_phase_information=False)
sc1.add(sp.sum(spaces=1)/fp2.sum())
sc2.add(sp.sum(spaces=0)/fp1.sum())
assert_allclose(sc1.mean.local_data, fp1.local_data, rtol=0.2)
assert_allclose(sc2.mean.local_data, fp2.local_data, rtol=0.2)
@expand(product([ift.RGSpace((8,), harmonic=True), (),
@pmp('space', [
ift.RGSpace((8,), harmonic=True), (),
ift.RGSpace((8, 8), harmonic=True, distances=0.123),
ift.RGSpace((2, 3, 7))]))
def test_norm(self, space):
ift.RGSpace((2, 3, 7))
])
def test_norm(space):
f = ift.Field.from_random("normal", domain=space, dtype=np.complex128)
gd = f.to_global_data().reshape(-1)
assert_allclose(f.norm(), np.linalg.norm(gd))
......@@ -121,31 +121,39 @@ class Test_Functionality(unittest.TestCase):
assert_allclose(f.norm(3), np.linalg.norm(gd, ord=3))
assert_allclose(f.norm(np.inf), np.linalg.norm(gd, ord=np.inf))
def test_vdot(self):
def test_vdot():
s = ift.RGSpace((10,))
f1 = ift.Field.from_random("normal", domain=s, dtype=np.complex128)
f2 = ift.Field.from_random("normal", domain=s, dtype=np.complex128)
assert_allclose(f1.vdot(f2), f1.vdot(f2, spaces=0))
assert_allclose(f1.vdot(f2), np.conj(f2.vdot(f1)))
def test_vdot2(self):
def test_vdot2():
x1 = ift.RGSpace((200,))
x2 = ift.RGSpace((150,))
m = ift.Field.full((x1, x2), .5)
res = m.vdot(m, spaces=1)
assert_allclose(res.local_data, 37.5)
def test_outer(self):
def test_outer():
x1 = ift.RGSpace((9,))
x2 = ift.RGSpace((3,))
m1 = ift.Field.full(x1, .5)
m2 = ift.Field.full(x2, 3.)
res = m1.outer(m2)
assert_allclose(res.to_global_data(), np.full((9, 3,), 1.5))
assert_allclose(res.to_global_data(), np.full((9, 3), 1.5))
def test_sum(self):
def test_sum():
x1 = ift.RGSpace((9,), distances=2.)
x2 = ift.RGSpace((2, 12,), distances=(0.3,))
x2 = ift.RGSpace(
(
2,
12,
), distances=(0.3,))
m1 = ift.Field.from_global_data(ift.makeDomain(x1), np.arange(9))
m2 = ift.Field.full(ift.makeDomain((x1, x2)), 0.45)
res1 = m1.sum()
......@@ -153,9 +161,10 @@ class Test_Functionality(unittest.TestCase):
assert_allclose(res1, 36)
assert_allclose(res2.to_global_data(), np.full(9, 2*12*0.45))
def test_integrate(self):
def test_integrate():
x1 = ift.RGSpace((9,), distances=2.)
x2 = ift.RGSpace((2, 12,), distances=(0.3,))
x2 = ift.RGSpace((2, 12), distances=(0.3,))
m1 = ift.Field.from_global_data(ift.makeDomain(x1), np.arange(9))
m2 = ift.Field.full(ift.makeDomain((x1, x2)), 0.45)
res1 = m1.integrate()
......@@ -163,41 +172,46 @@ class Test_Functionality(unittest.TestCase):
assert_allclose(res1, 36*2)
assert_allclose(res2.to_global_data(), np.full(9, 2*12*0.45*0.3**2))
def test_dataconv(self):
def test_dataconv():
s1 = ift.RGSpace((10,))
ld = np.arange(ift.dobj.local_shape(s1.shape)[0])
gd = np.arange(s1.shape[0])
assert_equal(ld, ift.from_local_data(s1, ld).local_data)
assert_equal(gd, ift.from_global_data(s1, gd).to_global_data())
def test_cast_domain(self):
def test_cast_domain():
s1 = ift.RGSpace((10,))
s2 = ift.RGSpace((10,), distances=20.)
d = np.arange(s1.shape[0])
d2 = ift.from_global_data(s1, d).cast_domain(s2).to_global_data()
assert_equal(d, d2)
def test_empty_domain(self):
def test_empty_domain():
f = ift.Field.full((), 5)
assert_equal(f.local_data, 5)
f = ift.Field.full(None, 5)
assert_equal(f.local_data, 5)
def test_trivialities(self):
def test_trivialities():
s1 = ift.RGSpace((10,))
f1 = ift.Field.full(s1, 27)
assert_equal(f1.local_data, f1.real.local_data)
f1 = ift.Field.full(s1, 27.+3j)
f1 = ift.Field.full(s1, 27. + 3j)
assert_equal(f1.real.local_data, 27.)
assert_equal(f1.imag.local_data, 3.)
assert_equal(f1.local_data, +f1.local_data)
assert_equal(f1.sum(), f1.sum(0))
f1 = ift.from_global_data(s1, np.arange(10))
# assert_equal(f1.min(), 0)
# assert_equal(f1.max(), 9)
# assert_equal(f1.min(), 0)
# assert_equal(f1.max(), 9)
assert_equal(f1.prod(), 0)
def test_weight(self):
def test_weight():
s1 = ift.RGSpace((10,))
f = ift.Field.full(s1, 10.)
f2 = f.weight(1)
......@@ -214,9 +228,10 @@ class Test_Functionality(unittest.TestCase):
assert_equal(f.scalar_weight(0), None)
assert_equal(f.scalar_weight((0,)), None)
@expand(product([ift.RGSpace(10), ift.GLSpace(10)],
[np.float64, np.complex128]))
def test_reduction(self, dom, dt):
@pmp('dom', [ift.RGSpace(10), ift.GLSpace(10)])
@pmp('dt', [np.float64, np.complex128])
def test_reduction(dom, dt):
s1 = ift.Field.full(dom, dt(1.))
assert_allclose(s1.mean(), 1.)
assert_allclose(s1.mean(0), 1.)
......@@ -225,7 +240,8 @@ class Test_Functionality(unittest.TestCase):
assert_allclose(s1.std(), 0., atol=1e-14)
assert_allclose(s1.std(0), 0., atol=1e-14)
def test_err(self):
def test_err():
s1 = ift.RGSpace((10,))
s2 = ift.RGSpace((11,))
f1 = ift.Field.full(s1, 27)
......@@ -251,7 +267,8 @@ class Test_Functionality(unittest.TestCase):
with assert_raises(TypeError):
ift.full(s1, [2, 3])
def test_stdfunc(self):
def test_stdfunc():
s = ift.RGSpace((200,))
f = ift.Field.full(s, 27)
assert_equal(f.local_data, 27)
......@@ -276,14 +293,15 @@ class Test_Functionality(unittest.TestCase):
assert_equal((f <= f2).local_data, f.local_data <= f2.local_data)
assert_equal((f != f2).local_data, f.local_data != f2.local_data)
assert_equal((f == f2).local_data, f.local_data == f2.local_data)
assert_equal((f+f2).local_data, f.local_data+f2.local_data)
assert_equal((f-f2).local_data, f.local_data-f2.local_data)
assert_equal((f + f2).local_data, f.local_data + f2.local_data)
assert_equal((f - f2).local_data, f.local_data - f2.local_data)
assert_equal((f*f2).local_data, f.local_data*f2.local_data)
assert_equal((f/f2).local_data, f.local_data/f2.local_data)
assert_equal((-f).local_data, -(f.local_data))
assert_equal(abs(f).local_data, abs(f.local_data))
def test_emptydomain(self):
def test_emptydomain():
f = ift.Field.full((), 3.)
assert_equal(f.sum(), 3.)
assert_equal(f.prod(), 3.)
......@@ -292,11 +310,14 @@ class Test_Functionality(unittest.TestCase):
assert_equal(f.local_data.size, 1)
assert_equal(f.vdot(f), 9.)
@expand(product([float(5), 5.],
[ift.RGSpace((8,), harmonic=True), ()],
["exp", "log", "sin", "cos", "tan", "sinh", "cosh", "sinc",
"absolute", "sign"]))
def test_funcs(self, num, dom, func):
@pmp('num', [float(5), 5.])
@pmp('dom', [ift.RGSpace((8,), harmonic=True), ()])
@pmp('func', [
"exp", "log", "sin", "cos", "tan", "sinh", "cosh", "sinc", "absolute",
"sign"
])
def test_funcs(num, dom, func):
num = 5
f = ift.Field.full(dom, num)
res = getattr(f, func)()
......
......@@ -15,26 +15,28 @@
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
import unittest
from itertools import product
from test.common import expand
import numpy as np
import pytest
import nifty5 as ift
import numpy as np
def _flat_PS(k):
return np.ones_like(k)
class Energy_Tests(unittest.TestCase):
@expand(product([ift.GLSpace(15),
pmp = pytest.mark.parametrize
@pmp('space', [
ift.GLSpace(15),
ift.RGSpace(64, distances=.789),
ift.RGSpace([32, 32], distances=.789)],
["tanh", "exp", ""],
[1, 1e-2, 1e2],
[4, 78, 23]))
def testGaussianEnergy(self, space, nonlinearity, noise, seed):
ift.RGSpace([32, 32], distances=.789)
])
@pmp('nonlinearity', ["tanh", "exp", ""])
@pmp('noise', [1, 1e-2, 1e2])
@pmp('seed', [4, 78, 23])
def test_gaussian_energy(space, nonlinearity, noise, seed):
np.random.seed(seed)
dim = len(space.shape)
hspace = space.get_default_codomain()
......@@ -43,13 +45,17 @@ class Energy_Tests(unittest.TestCase):
pspace = ift.PowerSpace(hspace, binbounds=binbounds)
Dist = ift.PowerDistributor(target=hspace, power_space=pspace)
xi0 = ift.Field.from_random(domain=hspace, random_type='normal')
# FIXME Needed?
xi0_var = ift.Linearization.make_var(xi0)