• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

WassimTenachi / PhySO / #15

10 Jun 2024 12:47AM UTC coverage: 80.984% (+28.9%) from 52.052%
#15

push

coveralls-python

WassimTenachi
monitoring test

26 of 27 new or added lines in 1 file covered. (96.3%)

131 existing lines in 18 files now uncovered.

6814 of 8414 relevant lines covered (80.98%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.61
/physo/physym/tests/functions_UnitTest.py
1
import time
1✔
2
import unittest
1✔
3
import numpy as np
1✔
4
import torch as torch
1✔
5
import matplotlib.pyplot as plt
1✔
6
import warnings
1✔
7

8
# Internal imports
9
from physo.physym import functions as Func
1✔
10
from physo.physym.functions import data_conversion, data_conversion_inv
1✔
11
from physo.physym.tokenize import make_tokens
1✔
12

13
# Test token and output shapes
14
def test_one_token(tester, token):
1✔
15
    data0 = data_conversion ( np.arange(-5, 5, 0.5)     )
1✔
16
    data1 = data_conversion ( np.arange(-5, 5, 0.5) + 1 )
1✔
17
    data2 = data_conversion ( np.arange(-5, 5, 0.5) * 2 )   # 0 in same place as data0
1✔
18
    pi    = data_conversion ( np.array(np.pi) )
1✔
19
    large = data_conversion ( np.array(1e10)  )   # large float
1✔
20
    n_data = len(data0)
1✔
21

22
    # Binary
23
    if token.arity == 2:
1✔
24
        tester.assertEqual(len( data_conversion_inv ( token(data0, data1)              )) , n_data)   # np.array    , np.array
1✔
25
        tester.assertEqual(len( data_conversion_inv ( token(data0, data2)              )) , n_data)   # np.array    , np.array with (0,0)
1✔
26
        tester.assertEqual(len( data_conversion_inv ( token(data0, pi   )              )) , n_data)   # np.array    , float
1✔
27
        tester.assertEqual(len( data_conversion_inv ( token(data0, large)              )) , n_data)   # np.array    , large float
1✔
28
        tester.assertEqual(len( data_conversion_inv ( token(large, data0)              )) , n_data)   # large float , np.array
1✔
29
        tester.assertEqual(len( data_conversion_inv ( token(*torch.stack((data0, data1))) )) , n_data)  # *[np. array    , np.array]
1✔
30
        # large float , large float
31
        # expecting length = 1 or n_data to be able to compute afterward
32
        out_len = np.shape(np.atleast_1d(
1✔
33
                                data_conversion_inv ( token(large, large)              )))
34
        tester.assertEqual(out_len == n_data or out_len == (1,), True)
1✔
35
    # Unary
36
    if token.arity == 1:
1✔
37
        tester.assertEqual(len( data_conversion_inv ( token(data0)                     )) , n_data)  # np.array
1✔
38
        # large float
39
        # expecting length = 1 or n_data to be able to compute afterward
40
        out_len = np.shape(np.atleast_1d(
1✔
41
                                data_conversion_inv ( token(large)                     )))
42
        tester.assertEqual(out_len == n_data or out_len == (1,), True)
1✔
43
    # Zero-arity
44
    if token.arity == 0:
1✔
45
        out_len = np.shape(np.atleast_1d(
1✔
46
                                data_conversion_inv( token()                           )))
47
        bool_works = (out_len == (n_data,) or out_len == (1,))
1✔
48
        tester.assertEqual(bool_works, True)
1✔
49

50

51
class FuncTest(unittest.TestCase):
1✔
52

53
    # Test all protected tokens and output shapes of their underlying functions
54
    def test_protected_tokens(self):
1✔
55
        my_tokens = make_tokens(op_names="all",  #
1✔
56
                                     constants={"pi": np.pi, "c": 3e8},
57
                                     use_protected_ops=True, )
58
        for token in my_tokens:
1✔
59
            test_one_token(tester=self, token=token)
1✔
60

61
    # Test all unprotected tokens and output shapes of their underlying functions
62
    def test_unprotected_tokens(self):
1✔
63
        my_tokens = make_tokens(op_names="all",
1✔
64
                                     constants={"pi": np.pi, "c": 3e8},
65
                                     use_protected_ops=False, )
66
        for token in my_tokens:
1✔
67
            test_one_token(tester=self, token=token)
1✔
68

69
    # Test that arity and complexity have the same values in protected and unprotected modes
70
    def test_protected_unprotected_same_attributes(self):
1✔
71
        unprotected_tokens = make_tokens(op_names="all", use_protected_ops=False, )
1✔
72
        protected_tokens   = make_tokens(op_names="all", use_protected_ops=True, )
1✔
73
        unprotected_tokens_names = np.array([token.name for token in unprotected_tokens])
1✔
74
        protected_tokens_names   = np.array([token.name for token in protected_tokens])
1✔
75
        for name in protected_tokens_names:
1✔
76
            # ------------------------------------ protected token ------------------------------------
77
            protected_token = protected_tokens[np.argwhere(protected_tokens_names == name)]
1✔
78
            # Check that there is only one version of current token in protected tokens
79
            self.assertEqual(np.array_equal(protected_token.shape, [1, 1]), True)
1✔
80
            protected_token = protected_token[0, 0]
1✔
81
            # ------------------------------------ unprotected token ------------------------------------
82
            unprotected_token = unprotected_tokens[np.argwhere(unprotected_tokens_names == name)]
1✔
83
            # Check that there is only one version of current token in unprotected tokens
84
            self.assertEqual(np.array_equal(unprotected_token.shape, [1, 1]), True)
1✔
85
            unprotected_token = unprotected_token[0, 0]
1✔
86
            # ---------------------------- check that attributes are the same ----------------------------
87
            for attribute_name, attribute_val in protected_token.__dict__.items():
1✔
88
                attribute_val_in_protected   = protected_token  .__dict__[attribute_name]
1✔
89
                attribute_val_in_unprotected = unprotected_token.__dict__[attribute_name]
1✔
90
                # Checking all attributes except function which is bound to be different in protected vs unprotected
91
                if attribute_name != "function":
1✔
92
                    # Do regular comparison for str (can not compare str using equal_nan=True)
93
                    if isinstance(attribute_val_in_protected   , str) or \
1✔
94
                       isinstance(attribute_val_in_unprotected , str):
95
                        is_equal = np.array_equal(attribute_val_in_protected  ,
1✔
96
                                                  attribute_val_in_unprotected,
97
                                                  equal_nan=False)
98
                    else:
99
                        is_equal = np.array_equal(attribute_val_in_protected  ,
1✔
100
                                                  attribute_val_in_unprotected,
101
                                                  equal_nan=True)
102
                    self.assertEqual(is_equal, True)
1✔
103

104
    # Test that arity of functions does not exceed the max nb of children
105
    def test_max_arity(self):
1✔
106
        protected_tokens = make_tokens(op_names="all", use_protected_ops=True, )
1✔
107
        for token in protected_tokens:
1✔
108
            self.assertIs(token.arity <= Func.Tok.MAX_ARITY, True)
1✔
109

110
    # Test that tokens pointing to data work
111
    def test_data_pointers_work(self):
1✔
112
        const_data0 = data_conversion ( np.random.rand() )
1✔
113
        const_data1 = data_conversion ( np.random.rand() )
1✔
114
        my_tokens = make_tokens(op_names="all",
1✔
115
                                     constants={"pi": np.pi, "const1": 1., "data0": const_data0,
116
                                                           "data1": const_data1}, )
117
        my_tokens_dict = {token.name: token for token in my_tokens}
1✔
118
        # test that tokens point to data
119
        bool = np.array_equal(data_conversion_inv ( my_tokens_dict["pi"]()    ) , np.pi)
1✔
120
        self.assertEqual(bool, True)
1✔
121
        bool = np.array_equal(data_conversion_inv ( my_tokens_dict["const1"]() ) , 1.)
1✔
122
        self.assertEqual(bool, True)
1✔
123
        bool = np.array_equal(data_conversion_inv ( my_tokens_dict["data0"]()  ) , const_data0)
1✔
124
        self.assertEqual(bool, True)
1✔
125
        bool = np.array_equal(data_conversion_inv ( my_tokens_dict["data1"]()  ) , const_data1)
1✔
126
        self.assertEqual(bool, True)
1✔
127
        ## test mul(data0,data1) === np.multiply(const_data0, const_data1)
128
        bool = np.array_equal(data_conversion_inv ( my_tokens_dict["mul"](my_tokens_dict["data0"](), my_tokens_dict["data1"]())),
1✔
129
                              data_conversion_inv ( my_tokens_dict["mul"].function(const_data0, const_data1)))
130
        self.assertEqual(bool, True)
1✔
131

132
    # Test that behavior objects contain different operation names
133
    # (eg. "add" must only have one unique behavior)
134
    def test_behavior_contain_different_ops(self):
1✔
135
        unprotected_tokens = make_tokens(op_names="all", use_protected_ops=False, )
1✔
136
        protected_tokens = make_tokens(op_names="all", use_protected_ops=True, )
1✔
137
        unprotected_tokens_names = [token.name for token in unprotected_tokens]
1✔
138
        protected_tokens_names = [token.name for token in protected_tokens]
1✔
139
        for name in unprotected_tokens_names+protected_tokens_names:
1✔
140
            count = 0
1✔
141
            for _, behavior in Func.OP_UNIT_BEHAVIORS_DICT.items():
1✔
142
                if (name in behavior.op_names): count+=1
1✔
143
            if count >1: self.fail("Token named %s appears in more than one behavior."%(name))
1✔
144

145
    # Test that each behavior has a unique identifier
146
    def test_behavior_have_unique_ids(self):
1✔
147
        ids = [behavior.behavior_id for _, behavior in Func.OP_UNIT_BEHAVIORS_DICT.items()]
1✔
148
        if not len(ids) == len(np.unique(ids)):
1✔
UNCOV
149
            self.fail("Behaviors ids are not unique, ids = %s"%(str(ids)))
×
150

151
    # Test that tokens encoded with dimensionless behavior id are dimensionless
152
    def test_behavior_dimensionless_are_dimensionless(self):
1✔
153
        dimensionless_id = Func.OP_UNIT_BEHAVIORS_DICT["UNARY_DIMENSIONLESS_OP"].behavior_id
1✔
154
        unprotected_tokens = make_tokens(op_names="all", use_protected_ops=False, )
1✔
155
        protected_tokens = make_tokens(op_names="all", use_protected_ops=True, )
1✔
156
        for token in unprotected_tokens.tolist() + protected_tokens.tolist():
1✔
157
            if token.behavior_id == dimensionless_id:
1✔
158
                self.assertEqual(token.is_constraining_phy_units, True)
1✔
159
                works_bool = np.array_equal(token.phy_units, np.zeros(Func.Tok.UNITS_VECTOR_SIZE))
1✔
160
                self.assertEqual(works_bool, True)
1✔
161

162
    # Test GroupUnitsBehavior
163
    def test_GroupUnitsBehavior (self):
1✔
164
        behavior_id_mul = Func.UNIT_BEHAVIORS_DICT["MULTIPLICATION_OP"].behavior_id
1✔
165
        behavior_id_div = Func.UNIT_BEHAVIORS_DICT["DIVISION_OP"]      .behavior_id
1✔
166
        group = Func.UNIT_BEHAVIORS_DICT["BINARY_MULTIPLICATIVE_OP"]
1✔
167
        # --- Vect 1 ---
168
        test_vect_ids   = np.array([behavior_id_mul]*int(1e4) + [behavior_id_div]*int(1e4),)
1✔
169
        batch_size = test_vect_ids.shape[0]
1✔
170
        # Should contain all True statements
171
        t0 = time.perf_counter()
1✔
172
        equal_test = group.is_id(test_vect_ids)
1✔
173
        t1 = time.perf_counter()
1✔
174
        # print("Eq time = %f ms"%((t1-t0)*1e3))
175
        works_bool = (equal_test.dtype == bool)
1✔
176
        self.assertEqual(works_bool, True)
1✔
177
        works_bool = np.array_equal(equal_test, np.full(shape=batch_size, fill_value=True))
1✔
178
        self.assertEqual(works_bool, True)
1✔
179
        # --- Vect 2 ---
180
        equal_test = group.is_id([behavior_id_mul, behavior_id_div, 999999999999])
1✔
181
        works_bool = (equal_test.dtype == bool)
1✔
182
        self.assertEqual(works_bool, True)
1✔
183
        works_bool = np.array_equal(equal_test, [True, True, False])
1✔
184
        self.assertEqual(works_bool, True)
1✔
185
        # --- Single value ---
186
        equal_test = group.is_id(behavior_id_mul)
1✔
187
        works_bool = (equal_test.dtype == bool)
1✔
188
        self.assertEqual(works_bool, True)
1✔
189
        works_bool = np.array_equal(equal_test, True)
1✔
190
        self.assertEqual(works_bool, True)
1✔
191
        # --- Single value ---
192
        equal_test = group.is_id(999999999999)
1✔
193
        works_bool = (equal_test.dtype == bool)
1✔
194
        self.assertEqual(works_bool, True)
1✔
195
        works_bool = np.array_equal(equal_test, False)
1✔
196
        self.assertEqual(works_bool, True)
1✔
197

198

199
    def test_protected_functions_plots (self):
1✔
200

201
        do_show = False
1✔
202
        do_save = False
1✔
203
        make_plots = do_show or do_save  # if either is true, make plots
1✔
204

205
        n_plot = int(1e4)
1✔
206

207
        if make_plots:
1✔
208
            # protected_div
UNCOV
209
            x1 = torch.ones(n_plot)
×
UNCOV
210
            x2 = torch.linspace(-0.1, 0.1, n_plot)
×
UNCOV
211
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
212
            ax.plot(x2, Func.protected_div(x1, x2)     , label="protected_div", color="k", linestyle="solid")
×
UNCOV
213
            ax.plot(x2, Func.protected_div(x1, -1 * x2), label="protected_div (neg num)", color="r", linestyle="dotted")
×
UNCOV
214
            ax.legend()
×
UNCOV
215
            if do_show: plt.show()
×
216
            if do_save: fig.savefig("protected_div.png")
×
217

218
            # protected_exp
UNCOV
219
            x1 = torch.linspace(0, 1.1*Func.EXP_THRESHOLD, n_plot)
×
UNCOV
220
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
221
            ax.plot(x1, Func.protected_exp(x1), label="protected_exp", color="k")
×
222
            ax.legend()
×
UNCOV
223
            if do_show: plt.show()
×
UNCOV
224
            if do_save: fig.savefig("protected_exp.png")
×
225

226
            # protected_log
UNCOV
227
            x1 = torch.linspace(-10*Func.EPSILON, 10*Func.EPSILON, n_plot)
×
228
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
229
            ax.plot(x1, Func.protected_log(x1), label="protected_log", color="k")
×
UNCOV
230
            ax.legend()
×
UNCOV
231
            if do_show: plt.show()
×
232
            if do_save: fig.savefig("protected_log.png")
×
233

234
            # protected_logabs
UNCOV
235
            x1 = torch.linspace(-10*Func.EPSILON, 10*Func.EPSILON, n_plot)
×
236
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
237
            ax.plot(x1, Func.protected_logabs(x1), label="protected_logabs", color="k")
×
UNCOV
238
            ax.legend()
×
UNCOV
239
            if do_show: plt.show()
×
UNCOV
240
            if do_save: fig.savefig("protected_logabs.png")
×
241

242
            # protected_sqrt
UNCOV
243
            x1 = torch.linspace(-10, 10, n_plot)
×
UNCOV
244
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
245
            ax.plot(x1, Func.protected_sqrt(x1), label="protected_sqrt", color="k")
×
UNCOV
246
            ax.legend()
×
UNCOV
247
            if do_show: plt.show()
×
248
            if do_save: fig.savefig("protected_sqrt.png")
×
249

250
            # protected_inv
UNCOV
251
            x1 = torch.linspace(-10*Func.EPSILON, 10*Func.EPSILON, n_plot)
×
252
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
253
            ax.plot(x1, Func.protected_inv(x1), label="protected_inv", color="k")
×
UNCOV
254
            ax.legend()
×
UNCOV
255
            if do_show: plt.show()
×
256
            if do_save: fig.savefig("protected_inv.png")
×
257

258
            # protected_expneg
UNCOV
259
            x1 = torch.linspace(-1.1*Func.EXP_THRESHOLD, 0, n_plot)
×
UNCOV
260
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
261
            ax.plot(x1, Func.protected_expneg(x1), label="protected_expneg", color="k")
×
262
            ax.legend()
×
263
            if do_show: plt.show()
×
UNCOV
264
            if do_save: fig.savefig("protected_expneg.png")
×
265

266
            # protected_n2
UNCOV
267
            x1 = torch.linspace(-2 * Func.INF, 2 * Func.INF, n_plot)
×
268
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
269
            ax.plot(x1, Func.protected_n2(x1), label="protected_n2", color="k")
×
UNCOV
270
            ax.legend()
×
271
            if do_show: plt.show()
×
UNCOV
272
            if do_save: fig.savefig("protected_n2.png")
×
273

274
            # protected_n3
275
            x1 = torch.linspace(-2 * Func.INF, 2 * Func.INF, n_plot)
×
UNCOV
276
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
277
            ax.plot(x1, Func.protected_n3(x1), label="protected_n3", color="k")
×
UNCOV
278
            ax.legend()
×
279
            if do_show: plt.show()
×
UNCOV
280
            if do_save: fig.savefig("protected_n3.png")
×
281

282
            # protected_n4
UNCOV
283
            x1 = torch.linspace(-2 * Func.INF, 2 * Func.INF, n_plot)
×
284
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
285
            ax.plot(x1, Func.protected_n4(x1), label="protected_n4", color="k")
×
UNCOV
286
            ax.legend()
×
UNCOV
287
            if do_show: plt.show()
×
288
            if do_save: fig.savefig("protected_n4.png")
×
289

290
            # protected_arcsin
291
            x1 = torch.linspace(-2, 2, n_plot)
×
UNCOV
292
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
293
            ax.plot(x1, Func.protected_arcsin(x1), label="protected_arcsin", color="k")
×
UNCOV
294
            ax.legend()
×
295
            if do_show: plt.show()
×
UNCOV
296
            if do_save: fig.savefig("protected_arcsin.png")
×
297

298
            # protected_arccos
299
            x1 = torch.linspace(-2, 2, n_plot)
×
UNCOV
300
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
301
            ax.plot(x1, Func.protected_arccos(x1), label="protected_arccos", color="k")
×
UNCOV
302
            ax.legend()
×
UNCOV
303
            if do_show: plt.show()
×
304
            if do_save: fig.savefig("protected_arccos.png")
×
305

306
            # protected_torch_pow
UNCOV
307
            x1 = torch.linspace(-0.1*Func.INF, Func.INF, n_plot)
×
308
            x2 = torch.linspace(-8, 8, n_plot)
×
UNCOV
309
            fig, ax = plt.subplots(1, 1, figsize=(20, 10))
×
UNCOV
310
            ax.plot(x1, Func.protected_torch_pow(x1, x2), label="protected_div", color="k", linestyle="solid")
×
311
            ax.legend()
×
UNCOV
312
            if do_show: plt.show()
×
UNCOV
313
            if do_save: fig.savefig("protected_torch_pow.png")
×
314

315
        return None
1✔
316

317
if __name__ == '__main__':
1✔
UNCOV
318
    unittest.main(verbosity=2)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc