File: testdynamicparams.py

package info (click to toggle)
python-param 2.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,048 kB
  • sloc: python: 17,980; makefile: 3
file content (284 lines) | stat: -rw-r--r-- 9,012 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
"""
Unit test for dynamic parameters.

Tests __get__, __set__ and that inspect_value() and
get_value_generator() work.

Originally implemented as doctests in Topographica in the file
testDynamicParameter.txt
"""
import copy
import unittest

import param
import numbergen


class TestDynamicParameters(unittest.TestCase):

    def setUp(self):
        super().setUp()
        param.Dynamic.time_dependent = False

        class TestPO1(param.Parameterized):
            x = param.Dynamic(default=numbergen.UniformRandom(lbound=-1,ubound=1,seed=1),doc="nothing")
            y = param.Dynamic(default=1)

        class TestPO2(param.Parameterized):
            x = param.Dynamic(default=numbergen.UniformRandom(lbound=-1,ubound=1,seed=30))
            y = param.Dynamic(default=1.0)

        self.TestPO2 = TestPO2
        self.TestPO1 = TestPO1

        self.t1 = self.TestPO1()
        self.t2 = self.TestPO1(x=numbergen.UniformRandom(lbound=-1,ubound=1,seed=10))
        self.t3 = self.TestPO1(x=numbergen.UniformRandom(lbound=-1,ubound=1,seed=10))
        self.t2.param.set_dynamic_time_fn(None)
        self.t3.param.set_dynamic_time_fn(None)

        self.t6 = self.TestPO2()
        self.t7 = self.TestPO2()


class TestDynamicParameterBasics(TestDynamicParameters):

    def test_set_dynamic_time_fn_x(self):
        self.t1.param.set_dynamic_time_fn(None)
        self.assertEqual(
            self.t1.param['x']._value_is_dynamic(self.t1), True)

    def test_set_dynamic_time_fn_y(self):
        self.assertEqual(
            self.t1.param['y']._value_is_dynamic(self.t1), False)

    def test_inspect_x(self):
        "no value generated yet"
        self.assertEqual(self.t1.param.inspect_value('x'), None)

    def test_inspect_y(self):
        self.assertEqual(self.t1.param.inspect_value('y'), 1)

    def test_inspect_y_set(self):
        self.t1.y = 2
        self.assertEqual(self.t1.param.inspect_value('y'), 2)

    def test_set_dynamic_numbergen(self):
        is_numbergen = isinstance(self.t2.param.get_value_generator('x'),
                                  numbergen.UniformRandom)
        self.assertEqual(is_numbergen, True)

    def test_matching_numbergen_streams(self):
        "check that t2 and t3 have identical streams"
        self.assertEqual(self.t2.x, self.t3.x)

    def test_numbergen_objects_distinct(self):
        "check t2 and t3 do not share UniformRandom objects"
        self.t2.x
        self.assertNotEqual(self.t2.param.inspect_value('x'),
                            self.t3.param.inspect_value('x'))

    def test_numbergen_inspect(self):
        " inspect_value() should return last generated value "
        self.t2.x # Call 1
        self.t2.x # Call 2
        t2_last_value = self.t2.x  # advance t2 beyond t3

        self.assertEqual(self.t2.param.inspect_value('x'),
                         t2_last_value)
        # ensure last_value is not shared
        self.assertNotEqual(self.t3.param.inspect_value('x'), t2_last_value)

    def test_dynamic_value_instantiated(self):
        t6_first_value = self.t6.x
        self.assertNotEqual(self.t7.param.inspect_value('x'),
                            t6_first_value)

    def test_non_dynamic_value_not_instantiated(self):
        "  non-dynamic value not instantiated"
        self.TestPO2.y = 4
        self.assertEqual(self.t6.y, 4)
        self.assertEqual(self.t7.y, 4)

    def test_dynamic_value_setting(self):
        self.t6.y = numbergen.UniformRandom()
        t8 = self.TestPO2()
        self.TestPO2.y = 10
        # t6 got a dynamic value, but shouldn't have changed Parameter's instantiate
        self.assertEqual(t8.y, 10)

    def test_setting_y_param_numbergen(self):
        self.TestPO2.y=numbergen.UniformRandom()  # now the Parameter instantiate should be true
        t9 = self.TestPO2()
        self.assertEqual('y' in t9._param__private.values, True)

    def test_shared_numbergen(self):
        """
        Instances of TestPO2 that don't have their own value for the
        parameter share one UniformRandom object
        """
        self.TestPO2.y=numbergen.UniformRandom()  # now the Parameter instantiate should be true
        self.assertEqual(self.t7.param.get_value_generator('y') is self.TestPO2().param['y'].default, True)
        self.assertEqual(self.TestPO2().param['y'].default.__class__.__name__, 'UniformRandom')

    def test_copy_match(self):
        "check a copy is the same"
        t9 = copy.deepcopy(self.t7)
        self.assertEqual(t9.param.get_value_generator('y') is self.TestPO2().param['y'].default, True)



class TestDynamicTimeDependent(TestDynamicParameters):

    def setUp(self):
        super().setUp()
        param.Dynamic.time_dependent = True

        class TestPO3(param.Parameterized):
            x = param.Dynamic(default=numbergen.UniformRandom(name='xgen',
                                                              time_dependent=True))

        class TestPO4(self.TestPO1):
            "Nested parameterized objects"
            z = param.Parameter(default=self.TestPO1())

        self.TestPO3 = TestPO3
        self.TestPO4 = TestPO4

        self.t10 = self.TestPO1()
        self.t11 = TestPO3()

    def test_dynamic_values_unchanged_dependent(self):
        param.Dynamic.time_dependent = True
        call_1 = self.t10.x
        call_2 = self.t10.x
        call_3 = self.t10.x
        self.assertEqual(call_1, call_2)
        self.assertEqual(call_2, call_3)

    def test_dynamic_values_changed_independent(self):
        param.Dynamic.time_dependent = False
        call_1 = self.t10.x
        call_2 = self.t10.x
        call_3 = self.t10.x
        self.assertNotEqual(call_1, call_2)
        self.assertNotEqual(call_2, call_3)

    def test_dynamic_values_change(self):
        param.Dynamic.time_dependent = True
        with param.Dynamic.time_fn as t:
            t(0)
            call_1 = self.t10.x
            t += 1
            call_2 = self.t10.x
            t(0)
            call_3 = self.t10.x
        self.assertNotEqual(call_1, call_2)
        self.assertNotEqual(call_1, call_3)

    def test_dynamic_values_time_dependent(self):
        param.Dynamic.time_dependent = True
        with param.Dynamic.time_fn as t:
            t(0)
            call_1 = self.t11.x
            t += 1
            call_2 = self.t11.x
            t(0)
            call_3 = self.t11.x
        self.assertNotEqual(call_1, call_2)
        self.assertEqual(call_1, call_3)

    def test_class_dynamic_values_change(self):
        call_1 = self.TestPO3.x
        call_2 = self.TestPO3.x
        self.assertEqual(call_1, call_2)
        with param.Dynamic.time_fn as t:
            t += 1
            call_3 = self.TestPO3.x
        self.assertNotEqual(call_2, call_3)

    def test_dynamic_value_change_independent(self):
        t12 = self.TestPO1()
        t12.param.set_dynamic_time_fn(None)
        self.assertNotEqual(t12.x, t12.x)
        self.assertEqual(t12.y, t12.y)

    def test_dynamic_value_change_disabled(self):
        " time_fn set on the UniformRandom() when t13.y was set"
        t13 = self.TestPO1()
        t13.param.set_dynamic_time_fn(None)
        t13.y = numbergen.UniformRandom()
        self.assertNotEqual(t13.y, t13.y)

    def test_dynamic_value_change_enabled(self):
        " time_fn set on the UniformRandom() when t13.y was set"
        t14 = self.TestPO1()
        t14.y = numbergen.UniformRandom()
        self.assertEqual(t14.y, t14.y)


    def test_dynamic_time_fn_not_inherited(self):
        " time_fn not inherited"
        t15 = self.TestPO4()
        t15.param.set_dynamic_time_fn(None)
        with param.Dynamic.time_fn as t:
            call_1 = t15.z.x
            t += 1
            call_2 = t15.z.x
            self.assertNotEqual(call_1, call_2)



class TestDynamicSharedNumbergen(TestDynamicParameters):
    "Check shared generator"
    def setUp(self):
        super().setUp()
        self.shared = numbergen.UniformRandom(lbound=-1,ubound=1,seed=20)

    def test_dynamic_shared_numbergen(self):
        param.Dynamic.time_dependent = True
        t11 = self.TestPO1(x=self.shared)
        t12 = self.TestPO1(x=self.shared)

        with param.Dynamic.time_fn as t:
            t += 1
            call_1 = t11.x
            self.assertEqual(call_1, t12.x)
            t += 1
            self.assertNotEqual(call_1, t12.x)


# Commented out block in the original doctest version.
# Maybe these are features originally planned but never implemented

# It is not yet possible to set time_fn for a Parameter instance
# >>> class TestPO5(param.Parameterized):
# ...    x = param.Dynamic(default=numbergen.UniformRandom(),dynamic_time_fn=None)

# We currently don't support iterators/generators in Dynamic unless
# they're wrapped.

# >>> i = iter([1,2,3])
# >>> t11.x = i

# >>> topo.sim.run(1)

# >>> t11.x
# 1

# >>> def gen():
# ...     yield 2
# ...     yield 4
# ...     yield 6

# >>> g = gen()

# >>> t11.x = g

# >>> t11.x
# 2

# >>> topo.sim.run(1)

# >>> t11.x
# 4