• 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

97.45
/physo/physym/tests/batch_UnitTest.py
1
import time
1✔
2
import unittest
1✔
3
import numpy as np
1✔
4
import torch
1✔
5

6
# Internal imports
7
from physo.physym import batch
1✔
8
from physo.physym.functions import data_conversion
1✔
9
from physo.physym import reward
1✔
10

11
class BatchTest(unittest.TestCase):
1✔
12

13

14
    def test_creation(self):
1✔
15

16
        # ------- TEST CASE -------
17
        DEVICE = 'cpu'
1✔
18
        if torch.cuda.is_available():
1✔
19
            DEVICE = 'cuda'
×
20

21
        # --- DATA ---
22
        N = int(1e6)
1✔
23
        x = data_conversion  (np.linspace(0.04, 4, N)  ).to(DEVICE)
1✔
24
        v = data_conversion  (np.linspace(0.10, 10, N) ).to(DEVICE)
1✔
25
        t = data_conversion  (np.linspace(0.06, 6, N)  ).to(DEVICE)
1✔
26
        X = torch.stack((x, v, t), axis=0)
1✔
27
        y = data_conversion(np.linspace(0.06, 6, N)).to(DEVICE)
1✔
28
        M  = data_conversion (1e6).to(DEVICE)
1✔
29
        c  = data_conversion (3e8).to(DEVICE)
1✔
30
        pi = data_conversion (np.pi).to(DEVICE)
1✔
31
        const1 = data_conversion (1.).to(DEVICE)
1✔
32

33
        # --- LIBRARY CONFIG ---
34
        args_make_tokens = {
1✔
35
                        # operations
36
                        "op_names"             : ["mul", "add", "neg", "inv", "cos"],
37
                        "use_protected_ops"    : True,
38
                        # input variables
39
                        "input_var_ids"        : {"x" : 0         , "v" : 1          , "t" : 2,        },
40
                        "input_var_units"      : {"x" : [1, 0, 0] , "v" : [1, -1, 0] , "t" : [0, 1, 0] },
41
                        "input_var_complexity" : {"x" : 0.        , "v" : 1.         , "t" : 0.,       },
42
                        # constants
43
                        "constants"            : {"pi" : pi        , "c" : c         , "M" : M         , "const1" : const1    },
44
                        "constants_units"      : {"pi" : [0, 0, 0] , "c" : [1, -1, 0], "M" : [0, 0, 1] , "const1" : [0, 0, 0] },
45
                        "constants_complexity" : {"pi" : 0.        , "c" : 0.        , "M" : 1.        , "const1" : 1.        },
46
                            }
47
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
48
                        "superparent_units" : [1, -2, 1],
49
                        "superparent_name"  : "y",
50
                        }
51

52
        # --- PRIORS ---
53
        priors_config  = [ ("UniformArityPrior", None),
1✔
54
                           ("HardLengthPrior", {"min_length": 1,
55
                                               "max_length": 8, }),]
56

57
        # --- BATCH ---
58
        batch_size    = 1000
1✔
59
        max_time_step = 30
1✔
60

61
        multi_X = [X,]
1✔
62
        multi_y = [y,]
1✔
63

64
        my_batch = batch.Batch(library_args     = library_args,
1✔
65
                               priors_config    = priors_config,
66
                               batch_size       = batch_size,
67
                               max_time_step    = max_time_step,
68
                               rewards_computer = reward.make_RewardsComputer (reward_function = reward.SquashedNRMSE),
69
                               multi_X = multi_X,
70
                               multi_y = multi_y,
71
                               )
72
        return None
1✔
73

74

75
    def test_dummy_epoch(self):
1✔
76

77
        # ------- TEST CASE -------
78
        DEVICE = 'cpu'
1✔
79
        if torch.cuda.is_available():
1✔
80
            DEVICE = 'cuda'
×
81

82
        # --- DATA ---
83
        N = int(1e3)
1✔
84
        x_array = np.linspace(0.04, 4, N)
1✔
85
        x = data_conversion (x_array).to(DEVICE)
1✔
86
        X = torch.stack((x,), axis=0)
1✔
87
        pi = data_conversion (np.pi).to(DEVICE)
1✔
88
        const1 = data_conversion (1.).to(DEVICE)
1✔
89
        T_array  = 1.028
1✔
90
        v0_array = 0.995
1✔
91
        T = data_conversion (T_array).to(DEVICE)
1✔
92
        v0 = data_conversion (v0_array).to(DEVICE)
1✔
93
        y_target = data_conversion(x_array/T_array + v0_array).to(DEVICE)
1✔
94

95
        # --- LIBRARY CONFIG ---
96
        args_make_tokens = {
1✔
97
                        # operations
98
                        "op_names"             : ["add", "div"],
99
                        "use_protected_ops"    : True,
100
                        # input variables
101
                        "input_var_ids"        : {"x" : 0         },
102
                        "input_var_units"      : {"x" : [1, 0, 0] },
103
                        "input_var_complexity" : {"x" : 1.        },
104
                        # constants
105
                        "constants"            : {"pi" : pi        , "const1" : const1    , "T" : T         , "v0" : v0         },
106
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] , "T" : [0, 1, 0] , "v0" : [1, -1, 0] },
107
                        "constants_complexity" : {"pi" : 1.        , "const1" : 1.        , "T" : 1.        , "v0" : 1.         },
108
                            }
109
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
110
                        "superparent_units" : [1, -1, 0],
111
                        "superparent_name"  : "v",
112
                        }
113

114
        # --- PRIORS ---
115
        priors_config  = [ ("UniformArityPrior", None),
1✔
116
                           ("HardLengthPrior", {"min_length": 1,
117
                                               "max_length": 5, }),
118
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
119

120
        # --- BATCH ---
121
        batch_size    = 1000
1✔
122
        max_time_step = 10
1✔
123

124
        multi_X = [X,]
1✔
125
        multi_y = [y_target,]
1✔
126

127
        my_batch = batch.Batch(library_args     = library_args,
1✔
128
                               priors_config    = priors_config,
129
                               batch_size       = batch_size,
130
                               max_time_step    = max_time_step,
131
                               rewards_computer = reward.make_RewardsComputer (reward_function = reward.SquashedNRMSE),
132
                               multi_X = multi_X,
133
                               multi_y = multi_y,
134
                               )
135

136
        # --- DUMMY EPOCH ---
137
        t0 = time.perf_counter()
1✔
138
        for step in range(max_time_step):
1✔
139
            # Embedding output
140
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
141
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
142
            # Dummy model output
143
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
144
            # Actions
145
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
146
            my_batch.programs.append(actions)
1✔
147
        # Embedding output
148
        lengths = my_batch.programs.n_lengths
1✔
149
        R       = my_batch.get_rewards()
1✔
150
        # Computing model loss using (probs,actions, R, lengths)
151
        # ...
152
        t1 = time.perf_counter()
1✔
153
        print("Dummy epoch time = %f ms"%((t1-t0)*1e3))
1✔
154

155
    def test_dummy_epoch_duplicate_elimination (self):
1✔
156

157
        # ------- TEST CASE -------
158
        DEVICE = 'cpu'
1✔
159
        if torch.cuda.is_available():
1✔
UNCOV
160
            DEVICE = 'cuda'
×
161

162
        # --- DATA ---
163
        N = int(1e3)
1✔
164
        x_array = np.linspace(0.04, 4, N)
1✔
165
        x = data_conversion (x_array).to(DEVICE)
1✔
166
        X = torch.stack((x,), axis=0)
1✔
167
        pi = data_conversion (np.pi).to(DEVICE)
1✔
168
        const1 = data_conversion (1.).to(DEVICE)
1✔
169
        T_array  = 1.028
1✔
170
        v0_array = 0.995
1✔
171
        T = data_conversion (T_array).to(DEVICE)
1✔
172
        v0 = data_conversion (v0_array).to(DEVICE)
1✔
173
        y_target = data_conversion(x_array/T_array + v0_array).to(DEVICE)
1✔
174

175
        # --- LIBRARY CONFIG ---
176
        args_make_tokens = {
1✔
177
                        # operations
178
                        "op_names"             : ["add", "div"],
179
                        "use_protected_ops"    : True,
180
                        # input variables
181
                        "input_var_ids"        : {"x" : 0         },
182
                        "input_var_units"      : {"x" : [1, 0, 0] },
183
                        "input_var_complexity" : {"x" : 1.        },
184
                        # constants
185
                        "constants"            : {"pi" : pi        , "const1" : const1    , "T" : T         , "v0" : v0         },
186
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] , "T" : [0, 1, 0] , "v0" : [1, -1, 0] },
187
                        "constants_complexity" : {"pi" : 1.        , "const1" : 1.        , "T" : 1.        , "v0" : 1.         },
188
                            }
189
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
190
                        "superparent_units" : [1, -1, 0],
191
                        "superparent_name"  : "v",
192
                        }
193

194
        # --- PRIORS ---
195
        priors_config  = [ ("UniformArityPrior", None),
1✔
196
                           ("HardLengthPrior", {"min_length": 1,
197
                                               "max_length": 5, }),
198
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
199

200
        # --- BATCH ---
201
        batch_size    = 1000
1✔
202
        max_time_step = 10
1✔
203

204
        multi_X = [X,]
1✔
205
        multi_y = [y_target,]
1✔
206

207
        my_batch = batch.Batch(library_args     = library_args,
1✔
208
                               priors_config    = priors_config,
209
                               batch_size       = batch_size,
210
                               max_time_step    = max_time_step,
211
                               rewards_computer = reward.make_RewardsComputer (reward_function = reward.SquashedNRMSE,
212
                                                                               zero_out_unphysical = True,
213
                                                                               zero_out_duplicates = True),
214
                               multi_X = multi_X,
215
                               multi_y = multi_y,
216
                               )
217

218
        # --- DUMMY EPOCH ---
219
        t0 = time.perf_counter()
1✔
220
        for step in range(max_time_step):
1✔
221
            # Embedding output
222
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
223
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
224
            # Dummy model output
225
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
226
            # Actions
227
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
228
            my_batch.programs.append(actions)
1✔
229
        # Embedding output
230
        lengths = my_batch.programs.n_lengths
1✔
231
        R       = my_batch.get_rewards()
1✔
232
        # Computing model loss using (probs,actions, R, lengths)
233
        # ...
234
        t1 = time.perf_counter()
1✔
235
        eps = 1e-5
1✔
236
        n_solutions = (np.abs(1-R) < eps).sum()
1✔
237
        n_kept = (R>0).sum()
1✔
238
        print("Dummy epoch time (w duplicate elimination) = %f ms (found %i/%i candidates with R > 0 "
1✔
239
              "and %i/%i with R = 1 +/- %f)"%((t1-t0)*1e3, n_kept, batch_size, n_solutions, batch_size, eps))
240

241
    def test_dummy_epoch_free_consts(self):
1✔
242

243
        # ------- TEST CASE -------
244
        DEVICE = 'cpu'
1✔
245
        if torch.cuda.is_available():
1✔
UNCOV
246
            DEVICE = 'cuda'
×
247

248
        # --- DATA ---
249
        N = int(1e3)
1✔
250
        x_array = np.linspace(0.04, 4, N)
1✔
251
        x = data_conversion (x_array).to(DEVICE)
1✔
252
        X = torch.stack((x,), axis=0)
1✔
253
        pi = data_conversion (np.pi).to(DEVICE)
1✔
254
        const1 = data_conversion (1.).to(DEVICE)
1✔
255
        T = 1.028
1✔
256
        v0 = 0.995
1✔
257
        y_target = data_conversion(x_array/T + v0).to(DEVICE)
1✔
258

259

260
        # --- LIBRARY CONFIG ---
261
        args_make_tokens = {
1✔
262
                        # operations
263
                        "op_names"             : ["add", "div"],
264
                        "use_protected_ops"    : True,
265
                        # input variables
266
                        "input_var_ids"        : {"x" : 0         },
267
                        "input_var_units"      : {"x" : [1, 0, 0] },
268
                        "input_var_complexity" : {"x" : 0.        },
269
                        # constants
270
                        "constants"            : {"pi" : pi        , "const1" : const1    },
271
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] },
272
                        "constants_complexity" : {"pi" : 0.        , "const1" : 1.        },
273
                        # free constants
274
                        "free_constants"            : {"T"              , "v0"              ,},
275
                        "free_constants_init_val"   : {"T" : 1.         , "v0" : 1.         ,},
276
                        "free_constants_units"      : {"T" : [0, 1, 0] , "v0" : [1, -1, 0] ,},
277
                        "free_constants_complexity" : {"T" : 0.         , "v0" : 0.         ,},
278
                            }
279
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
280
                        "superparent_units" : [1, -1, 0],
281
                        "superparent_name"  : "v",
282
                        }
283

284
        # --- PRIORS ---
285
        priors_config  = [ ("UniformArityPrior", None),
1✔
286
                           ("HardLengthPrior", {"min_length": 1,
287
                                               "max_length": 5, }),
288
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
289

290
        # --- FREE CONST OPTI ---
291
        free_const_opti_args = {
1✔
292
            'loss'   : "MSE",
293
            'method' : 'LBFGS',
294
            'method_args': {
295
                        'n_steps' : 30,
296
                        'tol'     : 1e-6,
297
                        'lbfgs_func_args' : {
298
                            'max_iter'       : 4,
299
                            'line_search_fn' : "strong_wolfe",
300
                                             },
301
                            },
302
        }
303

304
        # --- BATCH ---
305
        batch_size    = 1000
1✔
306
        max_time_step = 10
1✔
307

308
        multi_X = [X,]
1✔
309
        multi_y = [y_target,]
1✔
310

311
        my_batch = batch.Batch(library_args     = library_args,
1✔
312
                               priors_config    = priors_config,
313
                               batch_size       = batch_size,
314
                               max_time_step    = max_time_step,
315
                               rewards_computer = reward.make_RewardsComputer (reward_function     = reward.SquashedNRMSE,
316
                                                                               zero_out_unphysical = True),
317
                               free_const_opti_args = free_const_opti_args,
318
                               multi_X = multi_X,
319
                               multi_y = multi_y,
320
                               )
321

322
        # --- DUMMY EPOCH ---
323
        t0 = time.perf_counter()
1✔
324
        for step in range(max_time_step):
1✔
325
            # Embedding output
326
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
327
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
328
            # Dummy model output
329
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
330
            # Actions
331
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
332
            my_batch.programs.append(actions)
1✔
333
        # Embedding output
334
        lengths = my_batch.programs.n_lengths
1✔
335
        R       = my_batch.get_rewards()
1✔
336
        # Computing model loss using (probs,actions, R, lengths)
337
        # ...
338
        t1 = time.perf_counter()
1✔
339
        eps = 1e-5
1✔
340
        n_solutions = (np.abs(1-R) < eps).sum()
1✔
341
        print("Dummy epoch time (w free const) = %f ms (found %i/%i candidates with R = 1 +/- %f)"%((t1-t0)*1e3, n_solutions, batch_size, eps))
1✔
342

343
    def test_dummy_epoch_spe_free_consts_mdho2d(self):
1✔
344

345
        DEVICE = 'cpu'
1✔
346
        #if torch.cuda.is_available():
347
        #    DEVICE = 'cuda'
348

349
        # -------------------------------------- Making fake datasets --------------------------------------
350

351
        multi_X = []
1✔
352
        for n_samples in [90, 100, 110]:
1✔
353
            x1 = np.linspace(0, 10, n_samples)
1✔
354
            x2 = np.linspace(0, 1 , n_samples)
1✔
355
            X = np.stack((x1,x2),axis=0)
1✔
356
            X = torch.tensor(X).to(DEVICE)
1✔
357
            multi_X.append(X)
1✔
358
        multi_X = multi_X*10                         # (n_realizations,) of (n_dim, [n_samples depends on dataset],)
1✔
359

360
        n_samples_per_dataset = np.array([X.shape[1] for X in multi_X])
1✔
361
        n_all_samples = n_samples_per_dataset.sum()
1✔
362
        n_realizations = len(multi_X)
1✔
363
        def flatten_multi_data (multi_data,):
1✔
364
            """
365
            Flattens multiple datasets into a single one for vectorized evaluation.
366
            Parameters
367
            ----------
368
            multi_data : list of length (n_realizations,) of torch.tensor of shape (..., [n_samples depends on dataset],)
369
                List of datasets to be flattened.
370
            Returns
371
            -------
372
            torch.tensor of shape (..., n_all_samples)
373
                Flattened data (n_all_samples = sum([n_samples depends on dataset])).
374
            """
375
            flattened_data = torch.cat(multi_data, axis=-1) # (..., n_all_samples)
1✔
376
            return flattened_data
1✔
377

378
        def unflatten_multi_data (flattened_data):
1✔
379
            """
380
            Unflattens a single data into multiple ones.
381
            Parameters
382
            ----------
383
            flattened_data : torch.tensor of shape (..., n_all_samples)
384
                Flattened data (n_all_samples = sum([n_samples depends on dataset])).
385
            Returns
386
            -------
387
            list of len (n_realizations,) of torch.tensor of shape (..., [n_samples depends on dataset],)
388
                Unflattened data.
389
            """
390
            return list(torch.split(flattened_data, n_samples_per_dataset.tolist(), dim=-1)) # (n_realizations,) of (..., [n_samples depends on dataset],)
1✔
391

392
        #y_weights_per_dataset = np.array([0, 0.001, 1.0]*10) # Shows weights work
393
        y_weights_per_dataset = np.array([1., 1., 1.]*10)
1✔
394
        multi_y_weights = [np.full(shape=(n_samples_per_dataset[i],), fill_value=y_weights_per_dataset[i]) for i in range (n_realizations)]
1✔
395
        multi_y_weights = [torch.tensor(y_weights).to(DEVICE) for y_weights in multi_y_weights]
1✔
396
        y_weights_flatten = flatten_multi_data(multi_y_weights)
1✔
397

398
        multi_X_flatten = flatten_multi_data(multi_X)  # (n_dim, n_all_samples)
1✔
399

400
        # Making fake ideal parameters
401
        # n_spe_params   = 3
402
        # n_class_params = 2
403
        random_shift       = (np.random.rand(n_realizations,3)-0.5)*0.8
1✔
404
        ideal_spe_params   = torch.tensor(np.array([1.123, 0.345, 0.116]) + random_shift) # (n_realizations, n_spe_params,)
1✔
405
        ideal_spe_params   = ideal_spe_params.transpose(0,1)                              # (n_spe_params, n_realizations)
1✔
406
        ideal_class_params = torch.tensor(np.array([1.389, 1.005]))                       # (n_class_params, )
1✔
407

408
        ideal_spe_params_flatten = torch.cat(
1✔
409
            [torch.tile(ideal_spe_params[:,i], (n_samples_per_dataset[i],1)).transpose(0,1) for i in range (n_realizations)], # (n_realizations,) of (n_spe_params, [n_samples depends on dataset],)
410
            axis = 1
411
        ) # (n_spe_params, n_all_samples)
412

413
        ideal_class_params_flatten = torch.tile(ideal_class_params, (n_all_samples,1)).transpose(0,1) # (n_class_params, n_all_samples)
1✔
414

415
        def trial_func (X, params, class_params):
1✔
416
            y = params[0]*torch.exp(-params[1]*X[0])*torch.cos(class_params[0]*X[0]+params[2]) + class_params[1]*X[1]
1✔
417
            return y
1✔
418

419
        y_ideals_flatten = trial_func (multi_X_flatten, ideal_spe_params_flatten, ideal_class_params_flatten) # (n_all_samples,)
1✔
420
        multi_y_target   = unflatten_multi_data(y_ideals_flatten)                                         # (n_realizations,) of (n_samples depends on dataset,)
1✔
421

422
        k0_init = [1.,1.,1.]*10 # np.full(n_realizations, 1.)
1✔
423
        # consts
424
        pi     = data_conversion (np.pi) .to(DEVICE)
1✔
425
        const1 = data_conversion (1.)    .to(DEVICE)
1✔
426

427
        # LIBRARY CONFIG
428
        args_make_tokens = {
1✔
429
                        # operations
430
                        "op_names"             : "all",
431
                        "use_protected_ops"    : True,
432
                        # input variables
433
                        "input_var_ids"        : {"t" : 0         , "l" : 1          },
434
                        "input_var_units"      : {"t" : [0, 1, 0] , "l" : [1, 0, 0]  },
435
                        "input_var_complexity" : {"t" : 0.        , "l" : 1.         },
436
                        # constants
437
                        "constants"            : {"pi" : pi        , "const1" : const1    },
438
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] },
439
                        "constants_complexity" : {"pi" : 1.        , "const1" : 1.        },
440
                        # free constants
441
                        "class_free_constants"            : {"c0"              , "c1"               },
442
                        "class_free_constants_init_val"   : {"c0" : 1.         , "c1"  : 1.         },
443
                        "class_free_constants_units"      : {"c0" : [0, -1, 0] , "c1"  : [0, -1, 0] },
444
                        "class_free_constants_complexity" : {"c0" : 1.         , "c1"  : 1.         },
445
                        # free constants
446
                        "spe_free_constants"            : {"k0"              , "k1"               , "k2"               },
447
                        "spe_free_constants_init_val"   : {"k0" : k0_init    , "k1"  : 1.         , "k2"  : 1.         },
448
                        "spe_free_constants_units"      : {"k0" : [1, -1, 0] , "k1"  : [0, -1, 0] , "k2"  : [0, 0, 0]  },
449
                        "spe_free_constants_complexity" : {"k0" : 1.         , "k1"  : 1.         , "k2"  : 1.         },
450
                           }
451

452
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
453
                                "superparent_units" : [1, -1, 0],
454
                                "superparent_name"  : "v",
455
                                }
456

457
        # --- PRIORS ---
458
        priors_config  = [ ("UniformArityPrior", None),
1✔
459
                           ("HardLengthPrior", {"min_length": 1,
460
                                                "max_length": 20, }),
461
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
462

463
        # --- FREE CONST OPTI ---
464
        free_const_opti_args = {
1✔
465
            'loss'   : "MSE",
466
            'method' : 'LBFGS',
467
            'method_args': {
468
                        'n_steps' : 50,
469
                        'tol'     : 1e-6,
470
                        'lbfgs_func_args' : {
471
                            'max_iter'       : 4,
472
                            'line_search_fn' : "strong_wolfe",
473
                                             },
474
                            },
475
        }
476

477

478
        # --- BATCH ---
479
        batch_size    = 100
1✔
480
        max_time_step = 30
1✔
481

482
        my_batch = batch.Batch(library_args     = library_args,
1✔
483
                               priors_config    = priors_config,
484
                               batch_size       = batch_size,
485
                               max_time_step    = max_time_step,
486
                               rewards_computer = reward.make_RewardsComputer (reward_function     = reward.SquashedNRMSE,
487
                                                                               zero_out_unphysical = True,
488
                                                                               ),
489
                               free_const_opti_args = free_const_opti_args,
490
                               multi_X         = multi_X,
491
                               multi_y         = multi_y_target,
492
                               multi_y_weights = multi_y_weights,
493
                               )
494

495
        target_prog_str = ["add", "mul", "mul", "k0", "exp", "mul", "neg", "k1", "t", "cos", "add", "mul", "c0", "t",
1✔
496
                           "k2", "mul", "c1", "l", ]
497
        target_prog_idx = [my_batch.library.lib_name_to_idx[name] for name in target_prog_str]
1✔
498
        target_prog_idx += [0]*(max_time_step-len(target_prog_idx)) # Padding with zeros to max_time_step
1✔
499
        target_prog_idx = np.array(target_prog_idx)
1✔
500

501
        # --- DUMMY EPOCH ---
502
        t0 = time.perf_counter()
1✔
503
        for step in range(max_time_step):
1✔
504
            # Embedding output
505
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
506
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
507
            # Dummy model output
508
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
509
            # Cheating by setting the target program in the first batch element of probs
510
            probs[0]                        = 0.  # Zeroing out all probs
1✔
511
            probs[0, target_prog_idx[step]] = 1.  # Setting the target program to 1
1✔
512
            # Actions
513
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
514
            my_batch.programs.append(actions)
1✔
515
        # Embedding output
516
        lengths = my_batch.programs.n_lengths
1✔
517
        R       = my_batch.get_rewards()
1✔
518
        # Computing model loss using (probs,actions, R, lengths)
519
        # ...
520
        t1 = time.perf_counter()
1✔
521
        eps = 1e-3
1✔
522
        n_solutions = (np.abs(1-R) < eps).sum()
1✔
523
        print("Dummy epoch time (mdho2d scenario) = %f ms (found %i/%i candidates with R = 1 +/- %f)"%((t1-t0)*1e3, n_solutions, batch_size, eps))
1✔
524
        return None
1✔
525

526
    def test_dummy_epoch_free_consts_and_duplicate_elimination(self):
1✔
527

528
        # ------- TEST CASE -------
529
        DEVICE = 'cpu'
1✔
530
        if torch.cuda.is_available():
1✔
531
            DEVICE = 'cuda'
×
532

533
        # --- DATA ---
534
        N = int(1e3)
1✔
535
        x_array = np.linspace(0.04, 4, N)
1✔
536
        x = data_conversion (x_array).to(DEVICE)
1✔
537
        X = torch.stack((x,), axis=0)
1✔
538
        pi = data_conversion (np.pi).to(DEVICE)
1✔
539
        const1 = data_conversion (1.).to(DEVICE)
1✔
540
        T = 1.028
1✔
541
        v0 = 0.995
1✔
542
        y_target = data_conversion(x_array/T + v0).to(DEVICE)
1✔
543

544

545
        # --- LIBRARY CONFIG ---
546
        args_make_tokens = {
1✔
547
                        # operations
548
                        "op_names"             : ["add", "div"],
549
                        "use_protected_ops"    : True,
550
                        # input variables
551
                        "input_var_ids"        : {"x" : 0         },
552
                        "input_var_units"      : {"x" : [1, 0, 0] },
553
                        "input_var_complexity" : {"x" : 0.        },
554
                        # constants
555
                        "constants"            : {"pi" : pi        , "const1" : const1    },
556
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] },
557
                        "constants_complexity" : {"pi" : 0.        , "const1" : 1.        },
558
                        # free constants
559
                        "free_constants"            : {"T"              , "v0"              ,},
560
                        "free_constants_init_val"   : {"T" : 1.         , "v0" : 1.         ,},
561
                        "free_constants_units"      : {"T" : [0, 1, 0] , "v0" : [1, -1, 0] ,},
562
                        "free_constants_complexity" : {"T" : 0.         , "v0" : 0.         ,},
563
                            }
564
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
565
                        "superparent_units" : [1, -1, 0],
566
                        "superparent_name"  : "v",
567
                        }
568

569
        # --- PRIORS ---
570
        priors_config  = [ ("UniformArityPrior", None),
1✔
571
                           ("HardLengthPrior", {"min_length": 1,
572
                                               "max_length": 5, }),
573
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
574

575
        # --- FREE CONST OPTI ---
576
        free_const_opti_args = {
1✔
577
            'loss'   : "MSE",
578
            'method' : 'LBFGS',
579
            'method_args': {
580
                        'n_steps' : 30,
581
                        'tol'     : 1e-6,
582
                        'lbfgs_func_args' : {
583
                            'max_iter'       : 4,
584
                            'line_search_fn' : "strong_wolfe",
585
                                             },
586
                            },
587
        }
588

589
        # --- BATCH ---
590
        batch_size    = 1000
1✔
591
        max_time_step = 10
1✔
592

593
        multi_X = [X,]
1✔
594
        multi_y = [y_target,]
1✔
595

596
        my_batch = batch.Batch(library_args     = library_args,
1✔
597
                               priors_config    = priors_config,
598
                               batch_size       = batch_size,
599
                               max_time_step    = max_time_step,
600
                               rewards_computer = reward.make_RewardsComputer (reward_function     = reward.SquashedNRMSE,
601
                                                                               zero_out_unphysical = True,
602
                                                                               zero_out_duplicates = True,),
603
                               free_const_opti_args = free_const_opti_args,
604
                               multi_X = multi_X,
605
                               multi_y = multi_y,
606
                               )
607

608
        # --- DUMMY EPOCH ---
609
        t0 = time.perf_counter()
1✔
610
        for step in range(max_time_step):
1✔
611
            # Embedding output
612
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
613
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
614
            # Dummy model output
615
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
616
            # Actions
617
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
618
            my_batch.programs.append(actions)
1✔
619
        # Embedding output
620
        lengths = my_batch.programs.n_lengths
1✔
621
        R       = my_batch.get_rewards()
1✔
622
        # Computing model loss using (probs,actions, R, lengths)
623
        # ...
624
        t1 = time.perf_counter()
1✔
625
        eps = 1e-5
1✔
626
        n_solutions = (np.abs(1-R) < eps).sum()
1✔
627
        n_kept = (R>0).sum()
1✔
628
        print("Dummy epoch time (w free const and duplicate elimination) = %f ms (found %i/%i candidates with R > 0 "
1✔
629
              "and %i/%i with R = 1 +/- %f)"%((t1-t0)*1e3, n_kept, batch_size, n_solutions, batch_size, eps))
630

631
    def test_dummy_epoch_free_consts_and_duplicate_elimination_and_lowest_complexity(self):
1✔
632

633
        # ------- TEST CASE -------
634
        DEVICE = 'cpu'
1✔
635
        if torch.cuda.is_available():
1✔
636
            DEVICE = 'cuda'
×
637

638
        # --- DATA ---
639
        N = int(1e3)
1✔
640
        x_array = np.linspace(0.04, 4, N)
1✔
641
        x = data_conversion (x_array).to(DEVICE)
1✔
642
        X = torch.stack((x,), axis=0)
1✔
643
        pi = data_conversion (np.pi).to(DEVICE)
1✔
644
        const1 = data_conversion (1.).to(DEVICE)
1✔
645
        T = 1.028
1✔
646
        v0 = 0.995
1✔
647
        y_target = data_conversion(x_array/T + v0).to(DEVICE)
1✔
648

649

650
        # --- LIBRARY CONFIG ---
651
        args_make_tokens = {
1✔
652
                        # operations
653
                        "op_names"             : ["add", "div"],
654
                        "use_protected_ops"    : True,
655
                        # input variables
656
                        "input_var_ids"        : {"x" : 0         },
657
                        "input_var_units"      : {"x" : [1, 0, 0] },
658
                        "input_var_complexity" : {"x" : 0.        },
659
                        # constants
660
                        "constants"            : {"pi" : pi        , "const1" : const1    },
661
                        "constants_units"      : {"pi" : [0, 0, 0] , "const1" : [0, 0, 0] },
662
                        "constants_complexity" : {"pi" : 0.        , "const1" : 1.        },
663
                        # free constants
664
                        "free_constants"            : {"T"              , "v0"              ,},
665
                        "free_constants_init_val"   : {"T" : 1.         , "v0" : 1.         ,},
666
                        "free_constants_units"      : {"T" : [0, 1, 0] , "v0" : [1, -1, 0] ,},
667
                        "free_constants_complexity" : {"T" : 0.         , "v0" : 0.         ,},
668
                            }
669
        library_args = {"args_make_tokens"  : args_make_tokens,
1✔
670
                        "superparent_units" : [1, -1, 0],
671
                        "superparent_name"  : "v",
672
                        }
673

674
        # --- PRIORS ---
675
        priors_config  = [ ("UniformArityPrior", None),
1✔
676
                           ("HardLengthPrior", {"min_length": 1,
677
                                               "max_length": 5, }),
678
                           ("PhysicalUnitsPrior", {"prob_eps": np.finfo(np.float32).eps})]
679

680
        # --- FREE CONST OPTI ---
681
        free_const_opti_args = {
1✔
682
            'loss'   : "MSE",
683
            'method' : 'LBFGS',
684
            'method_args': {
685
                        'n_steps' : 30,
686
                        'tol'     : 1e-6,
687
                        'lbfgs_func_args' : {
688
                            'max_iter'       : 4,
689
                            'line_search_fn' : "strong_wolfe",
690
                                             },
691
                            },
692
        }
693

694
        # --- BATCH ---
695
        batch_size    = 1000
1✔
696
        max_time_step = 10
1✔
697

698
        multi_X = [X,]
1✔
699
        multi_y = [y_target,]
1✔
700

701
        my_batch = batch.Batch(library_args     = library_args,
1✔
702
                               priors_config    = priors_config,
703
                               batch_size       = batch_size,
704
                               max_time_step    = max_time_step,
705
                               rewards_computer = reward.make_RewardsComputer (reward_function     = reward.SquashedNRMSE,
706
                                                                               zero_out_unphysical = True,
707
                                                                               zero_out_duplicates = True,
708
                                                                               keep_lowest_complexity_duplicate = True),
709
                               free_const_opti_args = free_const_opti_args,
710
                               multi_X = multi_X,
711
                               multi_y = multi_y,
712
                               )
713

714
        # --- DUMMY EPOCH ---
715
        t0 = time.perf_counter()
1✔
716
        for step in range(max_time_step):
1✔
717
            # Embedding output
718
            prior        = torch.tensor(my_batch.prior().astype(np.float32),   requires_grad=False)                          # (batch_size, n_choices)
1✔
719
            observations = torch.tensor(my_batch.get_obs().astype(np.float32), requires_grad=False)                          # (batch_size, 3*n_choices+1)
1✔
720
            # Dummy model output
721
            probs        = torch.tensor(np.random.rand(my_batch.batch_size, my_batch.library.n_choices).astype(np.float32))  # (batch_size, n_choices,)
1✔
722
            # Actions
723
            actions      = torch.multinomial(probs * prior, num_samples=1)[:, 0]
1✔
724
            my_batch.programs.append(actions)
1✔
725
        # Embedding output
726
        lengths = my_batch.programs.n_lengths
1✔
727
        R       = my_batch.get_rewards()
1✔
728
        # Computing model loss using (probs,actions, R, lengths)
729
        # ...
730
        t1 = time.perf_counter()
1✔
731
        eps = 1e-5
1✔
732
        n_solutions = (np.abs(1-R) < eps).sum()
1✔
733
        n_kept = (R>0).sum()
1✔
734
        print("Dummy epoch time (w free const and duplicate elimination, keeping lowest complexity) = %f ms (found "
1✔
735
              "%i/%i candidates with R > 0 and %i/%i with R = 1 +/- %f)"%(
736
                (t1-t0)*1e3, n_kept, batch_size, n_solutions, batch_size, eps))
737

738
if __name__ == '__main__':
1✔
739
    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