@@ -476,6 +476,11 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
476
476
algorithm than regularized evolution, but does cycles 15%
477
477
faster. May be algorithmically less efficient.
478
478
Default is `False`.
479
+ turbo: bool
480
+ (Experimental) Whether to use LoopVectorization.jl to speed up the
481
+ search evaluation. Certain operators may not be supported.
482
+ Does not support 16-bit precision floats.
483
+ Default is `False`.
479
484
precision : int
480
485
What precision to use for the data. By default this is `32`
481
486
(float32), but you can select `64` or `16` as well, giving
@@ -692,6 +697,7 @@ def __init__(
692
697
batching = False ,
693
698
batch_size = 50 ,
694
699
fast_cycle = False ,
700
+ turbo = False ,
695
701
precision = 32 ,
696
702
random_state = None ,
697
703
deterministic = False ,
@@ -779,6 +785,7 @@ def __init__(
779
785
self .batching = batching
780
786
self .batch_size = batch_size
781
787
self .fast_cycle = fast_cycle
788
+ self .turbo = turbo
782
789
self .precision = precision
783
790
self .random_state = random_state
784
791
self .deterministic = deterministic
@@ -1518,25 +1525,22 @@ def _run(self, X, y, mutated_params, weights, seed):
1518
1525
str (self .early_stop_condition ) if self .early_stop_condition else None
1519
1526
)
1520
1527
1521
- mutation_weights = np .array (
1522
- [
1523
- self .weight_mutate_constant ,
1524
- self .weight_mutate_operator ,
1525
- self .weight_add_node ,
1526
- self .weight_insert_node ,
1527
- self .weight_delete_node ,
1528
- self .weight_simplify ,
1529
- self .weight_randomize ,
1530
- self .weight_do_nothing ,
1531
- ],
1532
- dtype = float ,
1528
+ mutation_weights = SymbolicRegression .MutationWeights (
1529
+ mutate_constant = self .weight_mutate_constant ,
1530
+ mutate_operator = self .weight_mutate_operator ,
1531
+ add_node = self .weight_add_node ,
1532
+ insert_node = self .weight_insert_node ,
1533
+ delete_node = self .weight_delete_node ,
1534
+ simplify = self .weight_simplify ,
1535
+ randomize = self .weight_randomize ,
1536
+ do_nothing = self .weight_do_nothing ,
1533
1537
)
1534
1538
1535
1539
# Call to Julia backend.
1536
1540
# See https://github.com/MilesCranmer/SymbolicRegression.jl/blob/master/src/OptionsStruct.jl
1537
1541
options = SymbolicRegression .Options (
1538
- binary_operators = Main .eval (str (tuple ( binary_operators ) ).replace ("'" , "" )),
1539
- unary_operators = Main .eval (str (tuple ( unary_operators ) ).replace ("'" , "" )),
1542
+ binary_operators = Main .eval (str (binary_operators ).replace ("'" , "" )),
1543
+ unary_operators = Main .eval (str (unary_operators ).replace ("'" , "" )),
1540
1544
bin_constraints = bin_constraints ,
1541
1545
una_constraints = una_constraints ,
1542
1546
complexity_of_operators = complexity_of_operators ,
@@ -1545,45 +1549,47 @@ def _run(self, X, y, mutated_params, weights, seed):
1545
1549
nested_constraints = nested_constraints ,
1546
1550
loss = custom_loss ,
1547
1551
maxsize = int (self .maxsize ),
1548
- hofFile = _escape_filename (self .equation_file_ ),
1552
+ output_file = _escape_filename (self .equation_file_ ),
1549
1553
npopulations = int (self .populations ),
1550
1554
batching = self .batching ,
1551
- batchSize = int (min ([batch_size , len (X )]) if self .batching else len (X )),
1552
- mutationWeights = mutation_weights ,
1553
- probPickFirst = self .tournament_selection_p ,
1554
- ns = self .tournament_selection_n ,
1555
+ batch_size = int (min ([batch_size , len (X )]) if self .batching else len (X )),
1556
+ mutation_weights = mutation_weights ,
1557
+ tournament_selection_p = self .tournament_selection_p ,
1558
+ tournament_selection_n = self .tournament_selection_n ,
1555
1559
# These have the same name:
1556
1560
parsimony = self .parsimony ,
1557
1561
alpha = self .alpha ,
1558
1562
maxdepth = maxdepth ,
1559
1563
fast_cycle = self .fast_cycle ,
1564
+ turbo = self .turbo ,
1560
1565
migration = self .migration ,
1561
- hofMigration = self .hof_migration ,
1562
- fractionReplacedHof = self .fraction_replaced_hof ,
1563
- shouldOptimizeConstants = self .should_optimize_constants ,
1564
- warmupMaxsizeBy = self .warmup_maxsize_by ,
1565
- useFrequency = self .use_frequency ,
1566
- useFrequencyInTournament = self .use_frequency_in_tournament ,
1566
+ hof_migration = self .hof_migration ,
1567
+ fraction_replaced_hof = self .fraction_replaced_hof ,
1568
+ should_optimize_constants = self .should_optimize_constants ,
1569
+ warmup_maxsize_by = self .warmup_maxsize_by ,
1570
+ use_frequency = self .use_frequency ,
1571
+ use_frequency_in_tournament = self .use_frequency_in_tournament ,
1567
1572
npop = self .population_size ,
1568
- ncyclesperiteration = self .ncyclesperiteration ,
1569
- fractionReplaced = self .fraction_replaced ,
1573
+ ncycles_per_iteration = self .ncyclesperiteration ,
1574
+ fraction_replaced = self .fraction_replaced ,
1570
1575
topn = self .topn ,
1571
1576
verbosity = self .verbosity ,
1572
1577
optimizer_algorithm = self .optimizer_algorithm ,
1573
1578
optimizer_nrestarts = self .optimizer_nrestarts ,
1574
- optimize_probability = self .optimize_probability ,
1579
+ optimizer_probability = self .optimize_probability ,
1575
1580
optimizer_iterations = self .optimizer_iterations ,
1576
- perturbationFactor = self .perturbation_factor ,
1581
+ perturbation_factor = self .perturbation_factor ,
1577
1582
annealing = self .annealing ,
1578
- stateReturn = True , # Required for state saving.
1583
+ return_state = True , # Required for state saving.
1579
1584
progress = progress ,
1580
1585
timeout_in_seconds = self .timeout_in_seconds ,
1581
- crossoverProbability = self .crossover_probability ,
1586
+ crossover_probability = self .crossover_probability ,
1582
1587
skip_mutation_failures = self .skip_mutation_failures ,
1583
1588
max_evals = self .max_evals ,
1584
- earlyStopCondition = early_stop_condition ,
1589
+ early_stop_condition = early_stop_condition ,
1585
1590
seed = seed ,
1586
1591
deterministic = self .deterministic ,
1592
+ define_helper_functions = False ,
1587
1593
)
1588
1594
1589
1595
# Convert data to desired precision
@@ -1603,7 +1609,16 @@ def _run(self, X, y, mutated_params, weights, seed):
1603
1609
else :
1604
1610
Main .weights = None
1605
1611
1606
- cprocs = 0 if multithreading else self .procs
1612
+ if self .procs == 0 and not multithreading :
1613
+ parallelism = "serial"
1614
+ elif multithreading :
1615
+ parallelism = "multithreading"
1616
+ else :
1617
+ parallelism = "multiprocessing"
1618
+
1619
+ cprocs = (
1620
+ None if parallelism in ["serial" , "multithreading" ] else int (self .procs )
1621
+ )
1607
1622
1608
1623
# Call to Julia backend.
1609
1624
# See https://github.com/MilesCranmer/SymbolicRegression.jl/blob/master/src/SymbolicRegression.jl
@@ -1614,8 +1629,8 @@ def _run(self, X, y, mutated_params, weights, seed):
1614
1629
niterations = int (self .niterations ),
1615
1630
varMap = self .feature_names_in_ .tolist (),
1616
1631
options = options ,
1617
- numprocs = int ( cprocs ) ,
1618
- multithreading = bool ( multithreading ) ,
1632
+ numprocs = cprocs ,
1633
+ parallelism = parallelism ,
1619
1634
saved_state = self .raw_julia_state_ ,
1620
1635
addprocs_function = cluster_manager ,
1621
1636
)
0 commit comments