test_power_space.py 6.22 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# NIFTy
# Copyright (C) 2017  Theo Steininger
#
# Author: Theo Steininger
#
# 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/>.

19
20
21
22
23
24
25
26
from __future__ import division

import unittest
import numpy as np

from d2o import distributed_data_object
from numpy.testing import assert_, assert_equal, assert_almost_equal,\
        assert_raises
Theo Steininger's avatar
Theo Steininger committed
27
from nifty import PowerSpace, RGSpace, Space
28
29
30
from types import NoneType
from test.common import expand

Theo Steininger's avatar
Theo Steininger committed
31
# [harmonic_partner, distribution_strategy,
Theo Steininger's avatar
Theo Steininger committed
32
#  logarithmic, nbin, binbounds, expected]
33
CONSTRUCTOR_CONFIGS = [
Martin Reinecke's avatar
Martin Reinecke committed
34
35
36
    [1, 'not', False, None, None, {'error': ValueError}],
    [RGSpace((8,)), 'not', False, None, None, {'error': ValueError}],
    [RGSpace((8,), harmonic=True), 'not', False, None, None, {
37
38
39
40
        'harmonic': True,
        'shape': (5,),
        'dim': 5,
        'total_volume': 8.0,
Theo Steininger's avatar
Theo Steininger committed
41
        'harmonic_partner': RGSpace((8,), harmonic=True),
Theo Steininger's avatar
Theo Steininger committed
42
        'logarithmic': False,
43
44
45
46
47
48
49
50
        'nbin': None,
        'binbounds': None,
        'pindex': distributed_data_object([0, 1, 2, 3, 4, 3, 2, 1]),
        'kindex': np.array([0., 1., 2., 3., 4.]),
        'rho': np.array([1, 2, 2, 2, 1]),
        'pundex': np.array([0, 1, 2, 3, 4]),
        'k_array': np.array([0., 1., 2., 3., 4., 3., 2., 1.]),
        }],
Martin Reinecke's avatar
Martin Reinecke committed
51
    [RGSpace((8,), harmonic=True), 'not', True, None, None, {
52
53
54
55
        'harmonic': True,
        'shape': (2,),
        'dim': 2,
        'total_volume': 8.0,
Theo Steininger's avatar
Theo Steininger committed
56
        'harmonic_partner': RGSpace((8,), harmonic=True),
Theo Steininger's avatar
Theo Steininger committed
57
        'logarithmic': True,
58
59
60
61
62
63
64
65
66
67
68
69
70
        'nbin': None,
        'binbounds': None,
        'pindex': distributed_data_object([0, 1, 1, 1, 1, 1, 1, 1]),
        'kindex': np.array([0., 2.28571429]),
        'rho': np.array([1, 7]),
        'pundex': np.array([0, 1]),
        'k_array': np.array([0., 2.28571429, 2.28571429, 2.28571429,
                             2.28571429, 2.28571429, 2.28571429, 2.28571429]),
        }],
    ]


def get_distance_array_configs():
Martin Reinecke's avatar
Martin Reinecke committed
71
    da_0 = np.array([0, 1.0, 1.41421356, 2., 2.23606798, 2.82842712])
72
    return [
Martin Reinecke's avatar
Martin Reinecke committed
73
        [RGSpace((4, 4), harmonic=True),  da_0],
74
75
76
77
        ]


def get_weight_configs():
Martin Reinecke's avatar
Martin Reinecke committed
78
79
80
81
82
83
84
85
86
    np.random.seed(42)

    # power 1
    w_0_x = np.random.rand(32, 16, 6)
    # RGSpace((4, 4), harmonic=True)
    # using rho directly
    weight_0 = np.array([1, 4, 4, 2, 4, 1])
    weight_0 = weight_0.reshape([1, 1, 6])
    w_0_res = w_0_x * weight_0
87
88
    return [
        [RGSpace((4, 4), harmonic=True),
Martin Reinecke's avatar
Martin Reinecke committed
89
            w_0_x, 1, (2,), False, w_0_res],
90
        [RGSpace((4, 4), harmonic=True),
Martin Reinecke's avatar
Martin Reinecke committed
91
            w_0_x.copy(), 1, (2,), True, w_0_res],
92
93
94
95
96
        ]


class PowerSpaceInterfaceTest(unittest.TestCase):
    @expand([
Theo Steininger's avatar
Theo Steininger committed
97
        ['harmonic_partner', Space],
Theo Steininger's avatar
Theo Steininger committed
98
        ['logarithmic', bool],
99
100
101
102
103
104
105
106
107
108
109
110
111
        ['nbin', (int, NoneType)],
        ['binbounds', (list, NoneType)],
        ['pindex', distributed_data_object],
        ['kindex', np.ndarray],
        ['rho', np.ndarray],
        ['pundex', np.ndarray],
        ['k_array', distributed_data_object],
        ])
    def test_property_ret_type(self, attribute, expected_type):
        r = RGSpace((4, 4), harmonic=True)
        p = PowerSpace(r)
        assert_(isinstance(getattr(p, attribute), expected_type))

112
113
114
115
116
class PowerSpaceConsistencyCheck(unittest.TestCase):
    @expand(CONSTRUCTOR_CONFIGS)
    def test_pipundexInversion(self, harmonic_partner, distribution_strategy,
                         logarithmic, nbin, binbounds, expected):
        #expected will not be used TODO: write expandproduct to use for this
Reimar H Leike's avatar
Reimar H Leike committed
117
118
119
120
121
122
123
124
        if 'error' in expected:
            with assert_raises(expected['error']):
                PowerSpace(harmonic_partner=harmonic_partner,
                           distribution_strategy=distribution_strategy,
                           logarithmic=logarithmic, nbin=nbin,
                           binbounds=binbounds)
        else:
            p = PowerSpace(harmonic_partner=harmonic_partner,
125
126
127
                           distribution_strategy=distribution_strategy,
                           logarithmic=logarithmic, nbin=nbin,
                           binbounds=binbounds)
Reimar H Leike's avatar
Reimar H Leike committed
128
            assert_equal(p.pindex[p.pundex],np.arange(p.dim),err_msg='pundex is not right-inverse of pindex!')
129
130
131

class PowerSpaceFunctionalityTest(unittest.TestCase):
    @expand(CONSTRUCTOR_CONFIGS)
Theo Steininger's avatar
Theo Steininger committed
132
    def test_constructor(self, harmonic_partner, distribution_strategy,
Theo Steininger's avatar
Theo Steininger committed
133
                         logarithmic, nbin, binbounds, expected):
134
135
        if 'error' in expected:
            with assert_raises(expected['error']):
Theo Steininger's avatar
Theo Steininger committed
136
                PowerSpace(harmonic_partner=harmonic_partner,
137
                           distribution_strategy=distribution_strategy,
Theo Steininger's avatar
Theo Steininger committed
138
139
                           logarithmic=logarithmic, nbin=nbin,
                           binbounds=binbounds)
140
        else:
Theo Steininger's avatar
Theo Steininger committed
141
            p = PowerSpace(harmonic_partner=harmonic_partner,
142
                           distribution_strategy=distribution_strategy,
Theo Steininger's avatar
Theo Steininger committed
143
144
                           logarithmic=logarithmic, nbin=nbin,
                           binbounds=binbounds)
145
146
147
148
149
150
151
            for key, value in expected.iteritems():
                if isinstance(value, np.ndarray):
                    assert_almost_equal(getattr(p, key), value)
                else:
                    assert_equal(getattr(p, key), value)

    @expand(get_distance_array_configs())
Theo Steininger's avatar
Theo Steininger committed
152
153
    def test_distance_array(self, harmonic_partner, expected):
        p = PowerSpace(harmonic_partner=harmonic_partner)
154
155
156
        assert_almost_equal(p.get_distance_array('not'), expected)

    @expand(get_weight_configs())
Theo Steininger's avatar
Theo Steininger committed
157
    def test_weight(self, harmonic_partner, x, power, axes,
158
                    inplace, expected):
Theo Steininger's avatar
Theo Steininger committed
159
        p = PowerSpace(harmonic_partner=harmonic_partner)
160
161
162
163
        res = p.weight(x, power, axes, inplace)
        assert_almost_equal(res, expected)
        if inplace:
            assert_(x is res)