Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d1a0d70
WIP Weak
Jacob-Stevens-Haas Sep 25, 2025
cdcf3b8
WIP: Easier reading for integration weights
Jacob-Stevens-Haas Oct 14, 2025
e8eccb2
WIP: Save before partition
Jacob-Stevens-Haas Oct 21, 2025
29f8492
Passes 1D change-of-variable test
Jacob-Stevens-Haas Nov 2, 2025
88372cb
Passes 2D change-of-variables test
Jacob-Stevens-Haas Nov 3, 2025
ade75e4
WIP
Jacob-Stevens-Haas Nov 4, 2025
a579d6b
TST: fix integrate_by_parts()
Jacob-Stevens-Haas Nov 25, 2025
9f7963b
Fix: Allow PDELibrary.get_params()
Jacob-Stevens-Haas Nov 25, 2025
51cfab4
WIP get integrate_product_by_parts
Jacob-Stevens-Haas Nov 27, 2025
1ff387e
feat: Make flatten_libraries() work
Jacob-Stevens-Haas Feb 3, 2026
6896544
feat: Make _integrate_by_parts() work
Jacob-Stevens-Haas Feb 3, 2026
8023547
Integrate time derivative w/test func
Jacob-Stevens-Haas Feb 4, 2026
e97c66b
Solve all the integrate by parts; reduce PDELibrary
Jacob-Stevens-Haas Feb 6, 2026
ae7c21c
Make weak feature names off of sorted_lib_
Jacob-Stevens-Haas Feb 6, 2026
f10ff1f
BLD: Bump min version to 3.11
Jacob-Stevens-Haas Feb 8, 2026
6067dfa
Extract test function to make testing easier
Jacob-Stevens-Haas Feb 8, 2026
9159c23
Make _plan_weak_form figure out correct term ordering
Jacob-Stevens-Haas Feb 13, 2026
5a8a4d5
wip
Jacob-Stevens-Haas Feb 17, 2026
9814b76
CLN: Fix input standardization
Jacob-Stevens-Haas Feb 19, 2026
b3de43f
fix: Make feature names line up in WeakSINDy
Jacob-Stevens-Haas Feb 19, 2026
831076e
CI: Add Weak Benchmark
Jacob-Stevens-Haas Feb 19, 2026
e1f438a
feat: Add smoothing to WeakSINDy and make it subclass SINDy.
Jacob-Stevens-Haas Feb 21, 2026
426d98f
fix: Fix weak form udot calc; add test
Jacob-Stevens-Haas Feb 21, 2026
70b56db
test(axes): Ensure einsum handles ellipsis names correctly
Jacob-Stevens-Haas Feb 22, 2026
d6a6980
test(weak): add tests for _eval_semiterm
Jacob-Stevens-Haas Feb 22, 2026
faaf1c0
feat(weak): Allow WeakSINDy to accept x_dot.
Jacob-Stevens-Haas Feb 24, 2026
6e321e6
CLN: Make weak SemiTerm a dataclass
Jacob-Stevens-Haas Feb 24, 2026
159b144
feat(weak): Allow WeakSINDy to accept x_dot.
Jacob-Stevens-Haas Feb 24, 2026
ac8572c
feat: add ParallelImplicitSINDy model (SINDy-PI)
Jacob-Stevens-Haas Feb 24, 2026
79b3082
DOC: add/improve docstrings in _weak.py
Jacob-Stevens-Haas Feb 24, 2026
7fa75ec
CLN: Linting/formatting
Jacob-Stevens-Haas Feb 25, 2026
3a3c9fb
DOC: Fix plot_directive in weak
Jacob-Stevens-Haas Feb 25, 2026
5543de7
fix: Call diff_method(), not private diff_method._differentiate()
Jacob-Stevens-Haas Feb 25, 2026
a2db3a2
CI: Only lint the diff, not all files
Jacob-Stevens-Haas Feb 25, 2026
56ddb85
fix: Explicitly unpack size-1 arrays when a scalar needed.
Jacob-Stevens-Haas Feb 25, 2026
aa12f01
CI: Restore prev ASV results before saving new ones
Jacob-Stevens-Haas Feb 25, 2026
0a7320c
fix: From copilot review, various
Jacob-Stevens-Haas Feb 27, 2026
9565f2f
cln: variable shadowing in _plan_weak_form
Jacob-Stevens-Haas Feb 27, 2026
46021ba
DOC: Consolidate PDE notebooks
Jacob-Stevens-Haas Feb 28, 2026
33ae312
fix: Specify how single/multiple H_xt trajectories passed
Jacob-Stevens-Haas Mar 7, 2026
55d5176
Add howto PDE example
Jacob-Stevens-Haas Mar 10, 2026
467a8ca
fix: Make predict match input shape
Jacob-Stevens-Haas Mar 13, 2026
9a62fa8
CLN: Review comments
Jacob-Stevens-Haas Mar 13, 2026
43d695d
fix: shape predictions correct in presence of controls
Jacob-Stevens-Haas Mar 13, 2026
68f2da1
TST: Bump sindy-exp dependency
Jacob-Stevens-Haas Mar 13, 2026
d66d5ff
Merge branch 'main' into weak
Jacob-Stevens-Haas Mar 24, 2026
8d51234
fix: weak adapt_multiple_traj, add test
Jacob-Stevens-Haas Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ exclude =
bin,
__pycache__
ignore =
W503 # Line break before binary operator - Conflicts black
E203 # Whitespace before ':' - Conflicts black
# Line break before binary operator - Conflicts black
W503
# Whitespace before ':' - Conflicts black
E203
per-file-ignores =
__init__.py:F401,F403
examples/**:E402,E501
Expand Down
52 changes: 41 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Linting
run: |
pip install pre-commit
pre-commit run --all-files
python-version: "3.12"
- uses: pre-commit/action@v3.0.1

build:
name: Build
Expand All @@ -34,7 +31,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
python-version: "3.12"
- name: build
run: pip install .
- name: test import
Expand All @@ -51,7 +48,7 @@ jobs:
- name: "Set up Python"
uses: actions/setup-python@v4
with:
python-version: "3.11"
python-version: "3.12"
- name: Install doc dependencies
run: |
sudo apt-get update -y
Expand All @@ -72,13 +69,12 @@ jobs:

tests:
name: Tests
needs: linting
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 4
matrix:
python-version: ["3.10", "3.12"]
python-version: ["3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -131,15 +127,18 @@ jobs:
contents: write # gh-pages publishing

steps:
# checkout code
- uses: actions/checkout@v4
with:
fetch-depth: 0 # ASV history

# Get Python
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

# Restore environment if it's cached
- name: Cache pip
uses: actions/cache@v4
with:
Expand All @@ -148,12 +147,14 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-

# Otherwise, restore environment
- name: Install dependencies
run: |
pip install --upgrade pip
pip install .[dev]
pip install asv

# Restore any cached ASV environments
- name: Cache ASV environments
uses: actions/cache@v4
with:
Expand All @@ -162,28 +163,57 @@ jobs:
restore-keys: |
asv-${{ runner.os }}-py${{ matrix.python-version }}-

# Detect machine information for benchmarks
- name: Setup ASV machine
run: |
cd asv_bench
asv machine --yes

# Check regressions of any benchmarks
- name: Check regression
if: github.event_name == 'pull_request'
run: |
cd asv_bench
git fetch origin $GITHUB_BASE_REF:base $GITHUB_REF:pr
asv continuous base pr -e

# This whole second section should be a separate workflow, triggered by
# commit to main, not PRs
# Checkout gh-pages into a side folder (if it exists)
- uses: actions/checkout@v4
continue-on-error: true
with:
ref: gh-pages
path: gh-pages

# Restore historical ASV results into workspace
- name: Restore ASV history
run: |
mkdir -p asv_bench/.asv/results
if [ -d gh-pages/.asv/results ]; then
rsync -a gh-pages/.asv/results/ asv_bench/.asv/results/
fi

# Generate website benchmark results for new commits
- name: Run benchmarks on main
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
cd asv_bench
asv run
asv run --skip-existing-successful
asv publish

# Stage site payload: html + updated results
- name: Prepare Pages payload
run: |
rm -rf pages && mkdir -p pages/.asv
rsync -a asv_bench/.asv/html/ pages/
rsync -a asv_bench/.asv/results/ pages/.asv/results/

# Deploy
- name: Deploy ASV dashboard to gh-pages
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: asv_bench/.asv/html
force_orphan: true
force_orphan: false
2 changes: 1 addition & 1 deletion .github/workflows/notebooks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
python-version: "3.11"
- name: Install dependencies
run: |
pip install .[cvxpy,miosr] sympy nbconvert jupyter matplotlib seaborn pandas dysts
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
python-version: "3.11"
- name: Install Build
run: |
python -m pip install --upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ repos:
hooks:
- id: reorder-python-imports
- repo: https://github.com/ambv/black
rev: 22.3.0
rev: 23.12.1
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
rev: 7.3.0
hooks:
- id: flake8
args: ["--config=.flake8"]
Expand Down
3 changes: 3 additions & 0 deletions asv_bench/asv.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"results_dir": ".asv/results",
"html_dir": ".asv/html",
"show_commit_url": "https://github.com/$OWNER/$REPO/commit/",
"install_command": [
"in-dir={env_dir} python -m pip install {wheel_file}[dev,miosr,cvxpy,sbr]"
],
"build_command": [
"python -m build --outdir {build_cache_dir} {build_dir}"
]
Expand Down
90 changes: 90 additions & 0 deletions asv_bench/benchmarks/defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from abc import ABC
from abc import abstractmethod

import sindy_exp
from asv_runner.benchmarks.mark import SkipNotImplemented

import pysindy as ps


class LorenzMixin:
def make_data(self):
trajectories, terms = sindy_exp.gen_data(
"lorenz", 4, noise_abs=0.1, dt=0.03, t_end=10
)["data"]
traj = trajectories[0]
self.true_eqns = terms
self.x = traj.x_train
self.x_dot_true = traj.x_train_true_dot
self.t = traj.t_train


class DefaultBM(ABC):
@abstractmethod
def make_data(self) -> None:
...

@abstractmethod
def make_model(self) -> None:
...

def setup(self):
self.make_data()
self.make_model()

def time_fit(self):
self.model.fit([self.x], [self.t])

def peakmem_fit(self):
self.model.fit([self.x], [self.t])

def track_score_fit(self):
self.model.fit([self.x], [self.t])
if not hasattr(self.model, "feature_names_"):
raise SkipNotImplemented
true_ode_align, est_ode_align = sindy_exp._utils.unionize_coeff_dicts(
self.model, self.true_eqns
)
metrics = sindy_exp.coeff_metrics(est_ode_align, true_ode_align)
return metrics["coeff_mae"]

def time_fit_predict(self):
self.model.fit([self.x], [self.t])
self.model.predict(self.x)

def peakmem_fit_predict(self):
self.model.fit([self.x], [self.t])
self.model.predict(self.x)

def track_score_fit_predict(self):
self.model.fit([self.x], [self.t])
self.model.predict(self.x)
metrics = sindy_exp.pred_metrics(
self.model, self.x, self.x_dot_true # type: ignore
)
return metrics["pred_l2_fro"]


class SINDyMixin:
def make_model(self):
self.model = ps.SINDy()


class SINDyLorenz(LorenzMixin, SINDyMixin, DefaultBM):
pass


class WeakMixin:
def make_model(self):
if not hasattr(ps, "WeakSINDy"):
raise SkipNotImplemented
self.model = ps.WeakSINDy()


class WeakLorenz(LorenzMixin, WeakMixin, DefaultBM):
pass


# class WeakHeat:

# class WeakBurgers:
Loading
Loading