Spaces:
Running
Running
Run in `Main`
Browse files- pysr/julia_helpers.py +7 -4
- pysr/sr.py +14 -18
- pysr/test/test.py +6 -6
pysr/julia_helpers.py
CHANGED
|
@@ -11,11 +11,8 @@ if os.environ.get("PYTHON_JULIACALL_HANDLE_SIGNALS", "yes") != "yes":
|
|
| 11 |
|
| 12 |
os.environ["PYTHON_JULIACALL_HANDLE_SIGNALS"] = "yes"
|
| 13 |
|
| 14 |
-
import juliacall
|
| 15 |
import juliapkg
|
| 16 |
-
|
| 17 |
-
jl = juliacall.newmodule("PySR")
|
| 18 |
-
|
| 19 |
from juliacall import convert as jl_convert
|
| 20 |
|
| 21 |
jl.seval("using PythonCall: PythonCall")
|
|
@@ -53,3 +50,9 @@ def _backend_version_assertion():
|
|
| 53 |
def _load_cluster_manager(cluster_manager):
|
| 54 |
jl.seval(f"using ClusterManagers: addprocs_{cluster_manager}")
|
| 55 |
return jl.seval(f"addprocs_{cluster_manager}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
os.environ["PYTHON_JULIACALL_HANDLE_SIGNALS"] = "yes"
|
| 13 |
|
|
|
|
| 14 |
import juliapkg
|
| 15 |
+
from juliacall import Main as jl
|
|
|
|
|
|
|
| 16 |
from juliacall import convert as jl_convert
|
| 17 |
|
| 18 |
jl.seval("using PythonCall: PythonCall")
|
|
|
|
| 50 |
def _load_cluster_manager(cluster_manager):
|
| 51 |
jl.seval(f"using ClusterManagers: addprocs_{cluster_manager}")
|
| 52 |
return jl.seval(f"addprocs_{cluster_manager}")
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def jl_array(x):
|
| 56 |
+
if x is None:
|
| 57 |
+
return None
|
| 58 |
+
return jl_convert(jl.Array, x)
|
pysr/sr.py
CHANGED
|
@@ -37,6 +37,7 @@ from .julia_helpers import (
|
|
| 37 |
_escape_filename,
|
| 38 |
_load_cluster_manager,
|
| 39 |
jl,
|
|
|
|
| 40 |
jl_convert,
|
| 41 |
)
|
| 42 |
from .utils import (
|
|
@@ -1618,8 +1619,8 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
|
|
| 1618 |
options = SymbolicRegression.Options(
|
| 1619 |
binary_operators=jl.seval(str(binary_operators).replace("'", "")),
|
| 1620 |
unary_operators=jl.seval(str(unary_operators).replace("'", "")),
|
| 1621 |
-
bin_constraints=
|
| 1622 |
-
una_constraints=
|
| 1623 |
complexity_of_operators=complexity_of_operators,
|
| 1624 |
complexity_of_constants=self.complexity_of_constants,
|
| 1625 |
complexity_of_variables=self.complexity_of_variables,
|
|
@@ -1684,16 +1685,16 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
|
|
| 1684 |
np_dtype = {32: np.complex64, 64: np.complex128}[self.precision]
|
| 1685 |
|
| 1686 |
# This converts the data into a Julia array:
|
| 1687 |
-
jl_X =
|
| 1688 |
if len(y.shape) == 1:
|
| 1689 |
-
jl_y =
|
| 1690 |
else:
|
| 1691 |
-
jl_y =
|
| 1692 |
if weights is not None:
|
| 1693 |
if len(weights.shape) == 1:
|
| 1694 |
-
jl_weights =
|
| 1695 |
else:
|
| 1696 |
-
jl_weights =
|
| 1697 |
else:
|
| 1698 |
jl_weights = None
|
| 1699 |
|
|
@@ -1711,17 +1712,12 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
|
|
| 1711 |
if len(y.shape) > 1:
|
| 1712 |
# We set these manually so that they respect Python's 0 indexing
|
| 1713 |
# (by default Julia will use y1, y2...)
|
| 1714 |
-
jl_y_variable_names =
|
| 1715 |
-
|
| 1716 |
)
|
| 1717 |
else:
|
| 1718 |
jl_y_variable_names = None
|
| 1719 |
|
| 1720 |
-
jl_feature_names = jl_convert(jl.Vector, self.feature_names_in_.tolist())
|
| 1721 |
-
jl_display_feature_names = jl_convert(
|
| 1722 |
-
jl.Vector, self.display_feature_names_in_.tolist()
|
| 1723 |
-
)
|
| 1724 |
-
|
| 1725 |
PythonCall.GC.disable()
|
| 1726 |
# Call to Julia backend.
|
| 1727 |
# See https://github.com/MilesCranmer/SymbolicRegression.jl/blob/master/src/SymbolicRegression.jl
|
|
@@ -1730,11 +1726,11 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
|
|
| 1730 |
jl_y,
|
| 1731 |
weights=jl_weights,
|
| 1732 |
niterations=int(self.niterations),
|
| 1733 |
-
variable_names=
|
| 1734 |
-
display_variable_names=
|
| 1735 |
y_variable_names=jl_y_variable_names,
|
| 1736 |
-
X_units=self.X_units_,
|
| 1737 |
-
y_units=self.y_units_,
|
| 1738 |
options=options,
|
| 1739 |
numprocs=cprocs,
|
| 1740 |
parallelism=parallelism,
|
|
|
|
| 37 |
_escape_filename,
|
| 38 |
_load_cluster_manager,
|
| 39 |
jl,
|
| 40 |
+
jl_array,
|
| 41 |
jl_convert,
|
| 42 |
)
|
| 43 |
from .utils import (
|
|
|
|
| 1619 |
options = SymbolicRegression.Options(
|
| 1620 |
binary_operators=jl.seval(str(binary_operators).replace("'", "")),
|
| 1621 |
unary_operators=jl.seval(str(unary_operators).replace("'", "")),
|
| 1622 |
+
bin_constraints=jl_array(bin_constraints),
|
| 1623 |
+
una_constraints=jl_array(una_constraints),
|
| 1624 |
complexity_of_operators=complexity_of_operators,
|
| 1625 |
complexity_of_constants=self.complexity_of_constants,
|
| 1626 |
complexity_of_variables=self.complexity_of_variables,
|
|
|
|
| 1685 |
np_dtype = {32: np.complex64, 64: np.complex128}[self.precision]
|
| 1686 |
|
| 1687 |
# This converts the data into a Julia array:
|
| 1688 |
+
jl_X = jl_array(np.array(X, dtype=np_dtype).T)
|
| 1689 |
if len(y.shape) == 1:
|
| 1690 |
+
jl_y = jl_array(np.array(y, dtype=np_dtype))
|
| 1691 |
else:
|
| 1692 |
+
jl_y = jl_array(np.array(y, dtype=np_dtype).T)
|
| 1693 |
if weights is not None:
|
| 1694 |
if len(weights.shape) == 1:
|
| 1695 |
+
jl_weights = jl_array(np.array(weights, dtype=np_dtype))
|
| 1696 |
else:
|
| 1697 |
+
jl_weights = jl_array(np.array(weights, dtype=np_dtype).T)
|
| 1698 |
else:
|
| 1699 |
jl_weights = None
|
| 1700 |
|
|
|
|
| 1712 |
if len(y.shape) > 1:
|
| 1713 |
# We set these manually so that they respect Python's 0 indexing
|
| 1714 |
# (by default Julia will use y1, y2...)
|
| 1715 |
+
jl_y_variable_names = jl_array(
|
| 1716 |
+
[f"y{_subscriptify(i)}" for i in range(y.shape[1])]
|
| 1717 |
)
|
| 1718 |
else:
|
| 1719 |
jl_y_variable_names = None
|
| 1720 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1721 |
PythonCall.GC.disable()
|
| 1722 |
# Call to Julia backend.
|
| 1723 |
# See https://github.com/MilesCranmer/SymbolicRegression.jl/blob/master/src/SymbolicRegression.jl
|
|
|
|
| 1726 |
jl_y,
|
| 1727 |
weights=jl_weights,
|
| 1728 |
niterations=int(self.niterations),
|
| 1729 |
+
variable_names=jl_array(self.feature_names_in_.tolist()),
|
| 1730 |
+
display_variable_names=jl_array(self.display_feature_names_in_.tolist()),
|
| 1731 |
y_variable_names=jl_y_variable_names,
|
| 1732 |
+
X_units=jl_array(self.X_units_),
|
| 1733 |
+
y_units=jl_array(self.y_units_),
|
| 1734 |
options=options,
|
| 1735 |
numprocs=cprocs,
|
| 1736 |
parallelism=parallelism,
|
pysr/test/test.py
CHANGED
|
@@ -106,11 +106,11 @@ class TestPipeline(unittest.TestCase):
|
|
| 106 |
warm_start=True,
|
| 107 |
)
|
| 108 |
model.fit(self.X, y)
|
| 109 |
-
from pysr.sr import
|
| 110 |
|
| 111 |
# We should have that the model state is now a Float64 hof:
|
| 112 |
-
|
| 113 |
-
self.assertTrue(
|
| 114 |
|
| 115 |
def test_multioutput_custom_operator_quiet_custom_complexity(self):
|
| 116 |
y = self.X[:, [0, 1]] ** 2
|
|
@@ -229,11 +229,11 @@ class TestPipeline(unittest.TestCase):
|
|
| 229 |
early_stop_condition=None,
|
| 230 |
)
|
| 231 |
# Check that the the julia state is saved:
|
| 232 |
-
from pysr.sr import
|
| 233 |
|
| 234 |
# We should have that the model state is now a Float32 hof:
|
| 235 |
-
|
| 236 |
-
self.assertTrue(
|
| 237 |
# This should exit almost immediately, and use the old equations
|
| 238 |
regressor.fit(X, y)
|
| 239 |
|
|
|
|
| 106 |
warm_start=True,
|
| 107 |
)
|
| 108 |
model.fit(self.X, y)
|
| 109 |
+
from pysr.sr import jl
|
| 110 |
|
| 111 |
# We should have that the model state is now a Float64 hof:
|
| 112 |
+
jl.test_state = model.raw_julia_state_
|
| 113 |
+
self.assertTrue(jl.seval("typeof(test_state[2]).parameters[1] == Float64"))
|
| 114 |
|
| 115 |
def test_multioutput_custom_operator_quiet_custom_complexity(self):
|
| 116 |
y = self.X[:, [0, 1]] ** 2
|
|
|
|
| 229 |
early_stop_condition=None,
|
| 230 |
)
|
| 231 |
# Check that the the julia state is saved:
|
| 232 |
+
from pysr.sr import jl
|
| 233 |
|
| 234 |
# We should have that the model state is now a Float32 hof:
|
| 235 |
+
jl.test_state = regressor.raw_julia_state_
|
| 236 |
+
self.assertTrue(jl.eval("typeof(test_state[2]).parameters[1] == Float32"))
|
| 237 |
# This should exit almost immediately, and use the old equations
|
| 238 |
regressor.fit(X, y)
|
| 239 |
|