MilesCranmer commited on
Commit
f2a280c
2 Parent(s): dafd19b 6dfed1b

Merge tag 'v0.18.4' into cleanup

Browse files
.github/workflows/CI.yml CHANGED
@@ -32,12 +32,12 @@ jobs:
32
  strategy:
33
  matrix:
34
  julia-version: ['1']
35
- python-version: ['3.11']
36
  os: [ubuntu-latest]
37
  test-id: [main]
38
  include:
39
  - julia-version: '1.6'
40
- python-version: '3.7'
41
  os: ubuntu-latest
42
  test-id: include
43
  - julia-version: '1'
@@ -99,11 +99,11 @@ jobs:
99
  strategy:
100
  matrix:
101
  os: ['ubuntu-latest']
102
- python-version: ['3.11']
103
  julia-version: ['1']
104
  include:
105
  - os: ubuntu-latest
106
- python-version: '3.7'
107
  julia-version: '1.6'
108
  steps:
109
  - uses: actions/checkout@v4
@@ -122,7 +122,7 @@ jobs:
122
  shell: bash -l {0}
123
  strategy:
124
  matrix:
125
- python-version: ['3.11']
126
  os: ['ubuntu-latest']
127
 
128
  steps:
@@ -181,8 +181,8 @@ jobs:
181
  strategy:
182
  matrix:
183
  python-version:
184
- - '3.11'
185
- - '3.7'
186
  os: ['ubuntu-latest']
187
 
188
  steps:
@@ -199,10 +199,10 @@ jobs:
199
  pip install mypy
200
  - name: "Install additional dependencies"
201
  run: python -m pip install jax jaxlib torch
202
- if: ${{ matrix.python-version != '3.7' }}
203
  - name: "Run mypy"
204
  run: python -m mypy --install-types --non-interactive pysr
205
- if: ${{ matrix.python-version != '3.7' }}
206
  - name: "Run compatible mypy"
207
  run: python -m mypy --ignore-missing-imports pysr
208
- if: ${{ matrix.python-version == '3.7' }}
 
32
  strategy:
33
  matrix:
34
  julia-version: ['1']
35
+ python-version: ['3.12']
36
  os: [ubuntu-latest]
37
  test-id: [main]
38
  include:
39
  - julia-version: '1.6'
40
+ python-version: '3.8'
41
  os: ubuntu-latest
42
  test-id: include
43
  - julia-version: '1'
 
99
  strategy:
100
  matrix:
101
  os: ['ubuntu-latest']
102
+ python-version: ['3.12']
103
  julia-version: ['1']
104
  include:
105
  - os: ubuntu-latest
106
+ python-version: '3.8'
107
  julia-version: '1.6'
108
  steps:
109
  - uses: actions/checkout@v4
 
122
  shell: bash -l {0}
123
  strategy:
124
  matrix:
125
+ python-version: ['3.12']
126
  os: ['ubuntu-latest']
127
 
128
  steps:
 
181
  strategy:
182
  matrix:
183
  python-version:
184
+ - '3.12'
185
+ - '3.8'
186
  os: ['ubuntu-latest']
187
 
188
  steps:
 
199
  pip install mypy
200
  - name: "Install additional dependencies"
201
  run: python -m pip install jax jaxlib torch
202
+ if: ${{ matrix.python-version != '3.8' }}
203
  - name: "Run mypy"
204
  run: python -m mypy --install-types --non-interactive pysr
205
+ if: ${{ matrix.python-version != '3.8' }}
206
  - name: "Run compatible mypy"
207
  run: python -m mypy --ignore-missing-imports pysr
208
+ if: ${{ matrix.python-version == '3.8' }}
.github/workflows/CI_Windows.yml CHANGED
@@ -30,7 +30,7 @@ jobs:
30
  strategy:
31
  matrix:
32
  julia-version: ['1']
33
- python-version: ['3.11']
34
  os: [windows-latest]
35
 
36
  steps:
 
30
  strategy:
31
  matrix:
32
  julia-version: ['1']
33
+ python-version: ['3.12']
34
  os: [windows-latest]
35
 
36
  steps:
.github/workflows/CI_docker_large_nightly.yml CHANGED
@@ -19,7 +19,7 @@ jobs:
19
  fail-fast: false
20
  matrix:
21
  julia-version: ['1.6', '1']
22
- python-version: ['3.7', '3.11']
23
  os: [ubuntu-latest]
24
  arch: ['linux/amd64', 'linux/arm64']
25
 
 
19
  fail-fast: false
20
  matrix:
21
  julia-version: ['1.6', '1']
22
+ python-version: ['3.8', '3.12']
23
  os: [ubuntu-latest]
24
  arch: ['linux/amd64', 'linux/arm64']
25
 
.github/workflows/CI_large_nightly.yml CHANGED
@@ -23,8 +23,8 @@ jobs:
23
  strategy:
24
  fail-fast: false
25
  matrix:
26
- julia-version: ['1.6', '1.8', '1.9']
27
- python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
28
  os: [ubuntu-latest, macos-latest, windows-latest]
29
 
30
  steps:
 
23
  strategy:
24
  fail-fast: false
25
  matrix:
26
+ julia-version: ['1.6', '1.8', '1.10']
27
+ python-version: ['3.8', '3.10', '3.12']
28
  os: [ubuntu-latest, macos-latest, windows-latest]
29
 
30
  steps:
.github/workflows/CI_mac.yml CHANGED
@@ -30,7 +30,7 @@ jobs:
30
  strategy:
31
  matrix:
32
  julia-version: ['1']
33
- python-version: ['3.11']
34
  os: [macos-latest]
35
 
36
  steps:
 
30
  strategy:
31
  matrix:
32
  julia-version: ['1']
33
+ python-version: ['3.12']
34
  os: [macos-latest]
35
 
36
  steps:
.github/workflows/docker_deploy.yml CHANGED
@@ -18,8 +18,8 @@ jobs:
18
  matrix:
19
  os: [ubuntu-latest]
20
  arch: [linux/amd64]
21
- python-version: [3.11.6]
22
- julia-version: [1.9.4]
23
  steps:
24
  - name: Checkout
25
  uses: actions/checkout@v4
 
18
  matrix:
19
  os: [ubuntu-latest]
20
  arch: [linux/amd64]
21
+ python-version: [3.12.3]
22
+ julia-version: [1.10.3]
23
  steps:
24
  - name: Checkout
25
  uses: actions/checkout@v4
docs/examples.md CHANGED
@@ -428,7 +428,7 @@ the evaluation, as we simply evaluated each argument and divided the result) int
428
  `((2.3554819 + -0.3554746) - (x1 * (x0 * x0)))` and
429
  `(-1.0000019 - (x2 * x2))`, meaning that our discovered equation is
430
  equal to:
431
- $\frac{x_0^2 x_1 - 2.0000073}{x_2^2 - 1.0000019}$, which
432
  is nearly the same as the true equation!
433
 
434
  ## 10. Dimensional constraints
@@ -520,6 +520,8 @@ a constant `"2.6353e-22[m s⁻²]"`.
520
 
521
  Note that this expression has a large dynamic range so may be difficult to find. Consider searching with a larger `niterations` if needed.
522
 
 
 
523
 
524
  ## 11. Additional features
525
 
 
428
  `((2.3554819 + -0.3554746) - (x1 * (x0 * x0)))` and
429
  `(-1.0000019 - (x2 * x2))`, meaning that our discovered equation is
430
  equal to:
431
+ $\frac{x_0^2 x_1 - 2.0000073}{x_2^2 + 1.0000019}$, which
432
  is nearly the same as the true equation!
433
 
434
  ## 10. Dimensional constraints
 
520
 
521
  Note that this expression has a large dynamic range so may be difficult to find. Consider searching with a larger `niterations` if needed.
522
 
523
+ Note that you can also search for exclusively dimensionless constants by settings
524
+ `dimensionless_constants_only` to `true`.
525
 
526
  ## 11. Additional features
527
 
environment.yml CHANGED
@@ -2,7 +2,7 @@ name: test
2
  channels:
3
  - conda-forge
4
  dependencies:
5
- - python>=3.7
6
  - sympy>=1.0.0,<2.0.0
7
  - pandas>=0.21.0,<3.0.0
8
  - numpy>=1.13.0,<2.0.0
 
2
  channels:
3
  - conda-forge
4
  dependencies:
5
+ - python>=3.8
6
  - sympy>=1.0.0,<2.0.0
7
  - pandas>=0.21.0,<3.0.0
8
  - numpy>=1.13.0,<2.0.0
pyproject.toml CHANGED
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
 
5
  [project]
6
  name = "pysr"
7
- version = "0.18.3"
8
  authors = [
9
  {name = "Miles Cranmer", email = "[email protected]"},
10
  ]
11
  description = "Simple and efficient symbolic regression"
12
  readme = {file = "README.md", content-type = "text/markdown"}
13
  license = {file = "LICENSE"}
14
- requires-python = ">=3.7"
15
  classifiers = [
16
  "Programming Language :: Python :: 3",
17
  "Operating System :: OS Independent",
@@ -34,5 +34,6 @@ profile = "black"
34
  dev-dependencies = [
35
  "pre-commit>=3.7.0",
36
  "ipython>=8.23.0",
 
37
  "mypy>=1.10.0",
38
  ]
 
4
 
5
  [project]
6
  name = "pysr"
7
+ version = "0.18.4"
8
  authors = [
9
  {name = "Miles Cranmer", email = "[email protected]"},
10
  ]
11
  description = "Simple and efficient symbolic regression"
12
  readme = {file = "README.md", content-type = "text/markdown"}
13
  license = {file = "LICENSE"}
14
+ requires-python = ">=3.8"
15
  classifiers = [
16
  "Programming Language :: Python :: 3",
17
  "Operating System :: OS Independent",
 
34
  dev-dependencies = [
35
  "pre-commit>=3.7.0",
36
  "ipython>=8.23.0",
37
+ "ipykernel>=6.29.4",
38
  "mypy>=1.10.0",
39
  ]
pysr/julia_import.py CHANGED
@@ -36,6 +36,11 @@ else:
36
  os.environ[k] = os.environ.get(k, default)
37
 
38
 
 
 
 
 
 
39
  from juliacall import Main as jl # type: ignore
40
 
41
  jl: Any = jl # type: ignore
@@ -43,28 +48,6 @@ jl: Any = jl # type: ignore
43
 
44
  jl_version = (jl.VERSION.major, jl.VERSION.minor, jl.VERSION.patch)
45
 
46
- # Next, automatically load the juliacall extension if we're in a Jupyter notebook
47
- autoload_extensions = os.environ.get("PYSR_AUTOLOAD_EXTENSIONS", "yes")
48
- if autoload_extensions in {"yes", ""} and jl_version >= (1, 9, 0):
49
- try:
50
- get_ipython = sys.modules["IPython"].get_ipython
51
-
52
- if "IPKernelApp" not in get_ipython().config:
53
- raise ImportError("console")
54
-
55
- print(
56
- "Detected Jupyter notebook. Loading juliacall extension. Set `PYSR_AUTOLOAD_EXTENSIONS=no` to disable."
57
- )
58
-
59
- # TODO: Turn this off if juliacall does this automatically
60
- get_ipython().run_line_magic("load_ext", "juliacall")
61
- except Exception:
62
- pass
63
- elif autoload_extensions not in {"no", "yes", ""}:
64
- warnings.warn(
65
- "PYSR_AUTOLOAD_EXTENSIONS environment variable is set to something other than 'yes' or 'no' or ''."
66
- )
67
-
68
  jl.seval("using SymbolicRegression")
69
  SymbolicRegression = jl.SymbolicRegression
70
 
 
36
  os.environ[k] = os.environ.get(k, default)
37
 
38
 
39
+ autoload_extensions = os.environ.get("PYSR_AUTOLOAD_EXTENSIONS")
40
+ if autoload_extensions is not None:
41
+ # Deprecated; so just pass to juliacall
42
+ os.environ["PYTHON_JULIACALL_AUTOLOAD_IPYTHON_EXTENSION"] = autoload_extensions
43
+
44
  from juliacall import Main as jl # type: ignore
45
 
46
  jl: Any = jl # type: ignore
 
48
 
49
  jl_version = (jl.VERSION.major, jl.VERSION.minor, jl.VERSION.patch)
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  jl.seval("using SymbolicRegression")
52
  SymbolicRegression = jl.SymbolicRegression
53
 
pysr/juliapkg.json CHANGED
@@ -3,7 +3,7 @@
3
  "packages": {
4
  "SymbolicRegression": {
5
  "uuid": "8254be44-1295-4e6a-a16d-46603ac705cb",
6
- "version": "=0.24.3"
7
  },
8
  "Serialization": {
9
  "uuid": "9e88b42a-f829-5b0c-bbe9-9e923198166b",
 
3
  "packages": {
4
  "SymbolicRegression": {
5
  "uuid": "8254be44-1295-4e6a-a16d-46603ac705cb",
6
+ "version": "=0.24.4"
7
  },
8
  "Serialization": {
9
  "uuid": "9e88b42a-f829-5b0c-bbe9-9e923198166b",
pysr/param_groupings.yml CHANGED
@@ -14,6 +14,7 @@
14
  - loss_function
15
  - model_selection
16
  - dimensional_constraint_penalty
 
17
  - Working with Complexities:
18
  - parsimony
19
  - constraints
 
14
  - loss_function
15
  - model_selection
16
  - dimensional_constraint_penalty
17
+ - dimensionless_constants_only
18
  - Working with Complexities:
19
  - parsimony
20
  - constraints
pysr/sr.py CHANGED
@@ -337,6 +337,9 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
337
  dimensional_constraint_penalty : float
338
  Additive penalty for if dimensional analysis of an expression fails.
339
  By default, this is `1000.0`.
 
 
 
340
  use_frequency : bool
341
  Whether to measure the frequency of complexities, and use that
342
  instead of parsimony to explore equation space. Will naturally
@@ -707,6 +710,7 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
707
  complexity_of_variables: Union[int, float] = 1,
708
  parsimony: float = 0.0032,
709
  dimensional_constraint_penalty: Optional[float] = None,
 
710
  use_frequency: bool = True,
711
  use_frequency_in_tournament: bool = True,
712
  adaptive_parsimony_scaling: float = 20.0,
@@ -802,6 +806,7 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
802
  self.complexity_of_variables = complexity_of_variables
803
  self.parsimony = parsimony
804
  self.dimensional_constraint_penalty = dimensional_constraint_penalty
 
805
  self.use_frequency = use_frequency
806
  self.use_frequency_in_tournament = use_frequency_in_tournament
807
  self.adaptive_parsimony_scaling = adaptive_parsimony_scaling
@@ -1693,6 +1698,7 @@ class PySRRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
1693
  # These have the same name:
1694
  parsimony=self.parsimony,
1695
  dimensional_constraint_penalty=self.dimensional_constraint_penalty,
 
1696
  alpha=self.alpha,
1697
  maxdepth=maxdepth,
1698
  fast_cycle=self.fast_cycle,
 
337
  dimensional_constraint_penalty : float
338
  Additive penalty for if dimensional analysis of an expression fails.
339
  By default, this is `1000.0`.
340
+ dimensionless_constants_only : bool
341
+ Whether to only search for dimensionless constants, if using units.
342
+ Default is `False`.
343
  use_frequency : bool
344
  Whether to measure the frequency of complexities, and use that
345
  instead of parsimony to explore equation space. Will naturally
 
710
  complexity_of_variables: Union[int, float] = 1,
711
  parsimony: float = 0.0032,
712
  dimensional_constraint_penalty: Optional[float] = None,
713
+ dimensionless_constants_only: bool = False,
714
  use_frequency: bool = True,
715
  use_frequency_in_tournament: bool = True,
716
  adaptive_parsimony_scaling: float = 20.0,
 
806
  self.complexity_of_variables = complexity_of_variables
807
  self.parsimony = parsimony
808
  self.dimensional_constraint_penalty = dimensional_constraint_penalty
809
+ self.dimensionless_constants_only = dimensionless_constants_only
810
  self.use_frequency = use_frequency
811
  self.use_frequency_in_tournament = use_frequency_in_tournament
812
  self.adaptive_parsimony_scaling = adaptive_parsimony_scaling
 
1698
  # These have the same name:
1699
  parsimony=self.parsimony,
1700
  dimensional_constraint_penalty=self.dimensional_constraint_penalty,
1701
+ dimensionless_constants_only=self.dimensionless_constants_only,
1702
  alpha=self.alpha,
1703
  maxdepth=maxdepth,
1704
  fast_cycle=self.fast_cycle,
pysr/test/test_startup.py CHANGED
@@ -118,10 +118,6 @@ class TestStartup(unittest.TestCase):
118
  code="import juliacall; import pysr",
119
  msg="juliacall module already imported.",
120
  ),
121
- dict(
122
- code='import os; os.environ["PYSR_AUTOLOAD_EXTENSIONS"] = "foo"; import pysr',
123
- msg="PYSR_AUTOLOAD_EXTENSIONS environment variable is set",
124
- ),
125
  ]
126
  for warning_test in warning_tests:
127
  result = subprocess.run(
 
118
  code="import juliacall; import pysr",
119
  msg="juliacall module already imported.",
120
  ),
 
 
 
 
121
  ]
122
  for warning_test in warning_tests:
123
  result = subprocess.run(
requirements.txt CHANGED
@@ -2,7 +2,7 @@ sympy>=1.0.0,<2.0.0
2
  pandas>=0.21.0,<3.0.0
3
  numpy>=1.13.0,<2.0.0
4
  scikit_learn>=1.0.0,<2.0.0
5
- juliacall==0.9.19
6
  click>=7.0.0,<9.0.0
7
  setuptools>=50.0.0
8
  typing_extensions>=4.0.0,<5.0.0; python_version < "3.8"
 
2
  pandas>=0.21.0,<3.0.0
3
  numpy>=1.13.0,<2.0.0
4
  scikit_learn>=1.0.0,<2.0.0
5
+ juliacall==0.9.20
6
  click>=7.0.0,<9.0.0
7
  setuptools>=50.0.0
8
  typing_extensions>=4.0.0,<5.0.0; python_version < "3.8"