kews 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. kews-0.1.0/LICENSE.txt +21 -0
  2. kews-0.1.0/MANIFEST.in +8 -0
  3. kews-0.1.0/PKG-INFO +173 -0
  4. kews-0.1.0/README.md +135 -0
  5. kews-0.1.0/examples/01a_bifur_harvesting.ipynb +415 -0
  6. kews-0.1.0/examples/01b_bifur_rosenzweig_macarthur_hopf.ipynb +500 -0
  7. kews-0.1.0/examples/02a_rate_saddle.ipynb +475 -0
  8. kews-0.1.0/examples/02b_rate_bautin.ipynb +462 -0
  9. kews-0.1.0/examples/03_amoc_model_ews.ipynb +966 -0
  10. kews-0.1.0/examples/README.md +13 -0
  11. kews-0.1.0/experiments/README.md +29 -0
  12. kews-0.1.0/experiments/__init__.py +1 -0
  13. kews-0.1.0/experiments/amoc/00_inspect_data.ipynb +228 -0
  14. kews-0.1.0/experiments/amoc/01a_full_analysis.ipynb +403 -0
  15. kews-0.1.0/experiments/amoc/01b_ablation_analysis.ipynb +306 -0
  16. kews-0.1.0/experiments/amoc/02_spectral_analysis.ipynb +554 -0
  17. kews-0.1.0/experiments/amoc/amoc_utils.py +217 -0
  18. kews-0.1.0/experiments/amoc/data/amoc_si_mldmax_2Juan.nc +0 -0
  19. kews-0.1.0/experiments/empirical/01_empirical_ews.ipynb +426 -0
  20. kews-0.1.0/experiments/empirical/empirical_utils.py +211 -0
  21. kews-0.1.0/experiments/indicators.py +104 -0
  22. kews-0.1.0/experiments/metrics.py +286 -0
  23. kews-0.1.0/experiments/systems/__init__.py +5 -0
  24. kews-0.1.0/experiments/systems/bifurcation/__init__.py +0 -0
  25. kews-0.1.0/experiments/systems/bifurcation/amoc.py +340 -0
  26. kews-0.1.0/experiments/systems/bifurcation/bifurcation_simulator.py +132 -0
  27. kews-0.1.0/experiments/systems/bifurcation/may_harvesting.py +351 -0
  28. kews-0.1.0/experiments/systems/bifurcation/rosenzweig_macarthur.py +468 -0
  29. kews-0.1.0/experiments/systems/generate.py +60 -0
  30. kews-0.1.0/experiments/systems/rate/__init__.py +0 -0
  31. kews-0.1.0/experiments/systems/rate/amoc.py +288 -0
  32. kews-0.1.0/experiments/systems/rate/bautin.py +279 -0
  33. kews-0.1.0/experiments/systems/rate/rate_simulator.py +139 -0
  34. kews-0.1.0/experiments/systems/rate/saddle_node.py +197 -0
  35. kews-0.1.0/experiments/systems/registry.py +128 -0
  36. kews-0.1.0/experiments/systems/types.py +41 -0
  37. kews-0.1.0/experiments/systems/utils.py +83 -0
  38. kews-0.1.0/kews/__init__.py +119 -0
  39. kews-0.1.0/kews/_core.py +441 -0
  40. kews-0.1.0/kews/diagnostics.py +116 -0
  41. kews-0.1.0/kews/observables.py +254 -0
  42. kews-0.1.0/kews.egg-info/PKG-INFO +173 -0
  43. kews-0.1.0/kews.egg-info/SOURCES.txt +48 -0
  44. kews-0.1.0/kews.egg-info/dependency_links.txt +1 -0
  45. kews-0.1.0/kews.egg-info/requires.txt +23 -0
  46. kews-0.1.0/kews.egg-info/top_level.txt +1 -0
  47. kews-0.1.0/pyproject.toml +53 -0
  48. kews-0.1.0/scripts/download_giss_nccs.py +311 -0
  49. kews-0.1.0/setup.cfg +4 -0
  50. kews-0.1.0/setup.py +3 -0
kews-0.1.0/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KEWS Developer Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
kews-0.1.0/MANIFEST.in ADDED
@@ -0,0 +1,8 @@
1
+ include README.md LICENSE.txt
2
+ recursive-include examples *.md *.ipynb
3
+ recursive-include experiments *.py *.md *.ipynb
4
+ prune experiments/empirical/data
5
+ prune experiments/amoc/data
6
+ include experiments/amoc/data/amoc_si_mldmax_2Juan.nc
7
+ recursive-include scripts *.py
8
+ global-exclude __pycache__ *.py[cod]
kews-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: kews
3
+ Version: 0.1.0
4
+ Summary: Koopman operator early warning signals
5
+ Author-email: Juan Nathaniel <jn2808@columbia.edu>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/juannat7/kews
8
+ Project-URL: Issues, https://github.com/juannat7/kews/issues
9
+ Project-URL: Paper, https://arxiv.org/abs/2608.14716
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Topic :: Scientific/Engineering
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE.txt
16
+ Requires-Dist: flax==0.12.4
17
+ Requires-Dist: jax==0.9.0.1
18
+ Requires-Dist: jaxlib==0.9.0.1
19
+ Requires-Dist: optax==0.2.6
20
+ Provides-Extra: paper
21
+ Requires-Dist: numpy==2.3.5; extra == "paper"
22
+ Requires-Dist: scipy==1.16.3; extra == "paper"
23
+ Requires-Dist: matplotlib==3.10.8; extra == "paper"
24
+ Requires-Dist: scikit-learn==1.8.0; extra == "paper"
25
+ Requires-Dist: pandas==3.0.0; extra == "paper"
26
+ Requires-Dist: xarray==2026.1.0; extra == "paper"
27
+ Requires-Dist: netCDF4==1.7.3; extra == "paper"
28
+ Requires-Dist: cmocean==4.0.3; extra == "paper"
29
+ Requires-Dist: requests==2.32.5; extra == "paper"
30
+ Requires-Dist: tqdm==4.67.1; extra == "paper"
31
+ Requires-Dist: jupyterlab==4.5.0; extra == "paper"
32
+ Requires-Dist: nbconvert==7.16.6; extra == "paper"
33
+ Requires-Dist: ipykernel==7.1.0; extra == "paper"
34
+ Provides-Extra: dev
35
+ Requires-Dist: build>=1.2; extra == "dev"
36
+ Requires-Dist: twine>=6; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # KEWS: Koopman Early Warning Signals
40
+
41
+ **KEWS** (pronounced “cues,” as in cues to potential tipping) is a JAX package for Koopman-based early warning signals of bifurcation- and rate-induced tipping.
42
+
43
+ <div align="center">
44
+
45
+ [![Python](https://img.shields.io/badge/Python-3.11%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
46
+ [![JAX](https://img.shields.io/badge/JAX-0.9-000000)](https://docs.jax.dev/)
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/juannat7/kews/blob/main/LICENSE.txt)
48
+ [![PyPI version](https://img.shields.io/pypi/v/kews)](https://pypi.org/project/kews/)
49
+ [![PyPI downloads](https://img.shields.io/pypi/dm/kews)](https://pypi.org/project/kews/)
50
+ [![arXiv](https://img.shields.io/badge/arXiv-2608.14716-b31b1b.svg)](https://arxiv.org/abs/2608.14716)
51
+
52
+ </div>
53
+
54
+ ## Abstract
55
+
56
+ Abrupt transitions in complex systems are often preceded by early warning signals. However, most indicators rely on the notion of critical slowing down and do not generally extend to rate-induced tipping where transitions can occur without local loss of stability. This is problematic in stochastic, nonautonomous systems where internal variability and time-varying variables interact to shape tipping onset.
57
+
58
+ We use Koopman operator theory to develop a unified early warning framework for both bifurcation and rate-induced tipping in stochastic systems. Our approach builds on residual Koopman mode decomposition that measures discrepancies between dynamics and their finite-dimensional approximation, and extends it to the control setting by augmenting the observable space with time-varying control variables.
59
+
60
+ In idealized examples, the resulting indicators recover expected signatures near bifurcation points and improve detection in rate-induced regimes where classical indicators fail. We further show that learned embeddings through deep learning outperform prescribed dictionaries, especially in a high-dimensional setting.
61
+
62
+ Applied to simulations of the Atlantic Meridional Overturning Circulation, our Koopman-based indicators distinguish tipping from non-tipping trajectories and reveal interpretable spectral signatures prior to critical transition.
63
+
64
+ ## Installation
65
+
66
+ Python 3.11 or newer is required. Install the library from PyPI:
67
+
68
+ ```bash
69
+ pip install kews
70
+ ```
71
+
72
+ To reproduce the paper or develop the code:
73
+
74
+ ```bash
75
+ git clone https://github.com/juannat7/kews.git
76
+ cd kews
77
+ pip install -e ".[paper,dev]"
78
+ ```
79
+
80
+ Reproduction instructions are in [examples](https://github.com/juannat7/kews/tree/main/examples) for the model systems and [experiments](https://github.com/juannat7/kews/tree/main/experiments) for the coupled AMOC and empirical cases.
81
+
82
+ ## Quickstart
83
+
84
+ Compute rolling ResKMD residuals from a scalar time series:
85
+
86
+ ```python
87
+ import jax.numpy as jnp
88
+ from jax import random
89
+
90
+ import kews
91
+ from kews.observables import time_delay
92
+
93
+ time = jnp.linspace(0, 10 * jnp.pi, 100)
94
+ state = jnp.sin(time) + 0.01 * random.normal(random.key(7), time.shape)
95
+
96
+ signal = kews.resdmd(
97
+ state,
98
+ window=50, # Window length in samples (or a fraction, e.g. 0.5)
99
+ observable=time_delay(n_delay=10), # Time-delay dictionary with 10 coordinates
100
+ rank=0.9, # Retain 90% of the SVD energy
101
+ )
102
+
103
+ # One residual per time step; the first 49 entries are NaN.
104
+ print(signal.shape) # (100,)
105
+ ```
106
+
107
+ ## Control-aware residuals
108
+
109
+ Pass a control time series aligned with the state:
110
+
111
+ ```python
112
+ control = jnp.linspace(-1, 1, state.size)
113
+ controlled_signal = kews.resdmd(
114
+ state,
115
+ window=50,
116
+ observable=time_delay(10),
117
+ control=control,
118
+ )
119
+ ```
120
+
121
+ ## Observable choices
122
+
123
+ Use fixed random Fourier features instead of delay coordinates:
124
+
125
+ ```python
126
+ from kews.observables import rff
127
+
128
+ random_signal = kews.resdmd(
129
+ state,
130
+ window=50,
131
+ observable=rff(n_features=100, scale=0.2, seed=7),
132
+ )
133
+ ```
134
+
135
+ The random basis stays fixed across windows. An autoencoder can learn the features:
136
+
137
+ ```python
138
+ from kews.observables import mlp
139
+
140
+ learned_signal = kews.resdmd(
141
+ state,
142
+ window=50,
143
+ observable=mlp(hidden_layers=(16, 8), bottleneck_dim=3, seed=7),
144
+ fit_kwargs={"epochs": 200, "batch_size": 32, "lr": 1e-3},
145
+ )
146
+ ```
147
+
148
+ Training uses only the first window; the encoder is then frozen. Create a new observable for each independent fit. Paper notebooks specify their full training settings.
149
+
150
+ ## Spectral diagnostics
151
+
152
+ ```python
153
+ from kews import diagnostics
154
+
155
+ fit = diagnostics.fit_operator(state, observable=time_delay(10), rank=0.9)
156
+ generator = diagnostics.generator_eigenvalues(fit["eigvals"], dt=1.0)
157
+ dominant = diagnostics.dominant_mode(generator, dt=1.0)
158
+ ```
159
+
160
+ `dt` is the sampling interval in the units of the input data. The mode summary includes decay rate, oscillation period, and e-folding time.
161
+
162
+ ## Citation
163
+
164
+ ```bibtex
165
+ @article{nathaniel2026koopman,
166
+ title={Koopman early warning signals for bifurcation and rate-induced tipping},
167
+ author={Nathaniel, Juan and Roesch, Carla and DeSantis, Derek and Kooloth, Parvathi and Fan, Hang and Lucarini, Valerio and Romanou, Anastasia and Gentine, Pierre},
168
+ journal={arXiv preprint arXiv:2608.14716},
169
+ year={2026}
170
+ }
171
+ ```
172
+
173
+ Code uses the [MIT license](https://github.com/juannat7/kews/blob/main/LICENSE.txt). External datasets retain their original terms.
kews-0.1.0/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # KEWS: Koopman Early Warning Signals
2
+
3
+ **KEWS** (pronounced “cues,” as in cues to potential tipping) is a JAX package for Koopman-based early warning signals of bifurcation- and rate-induced tipping.
4
+
5
+ <div align="center">
6
+
7
+ [![Python](https://img.shields.io/badge/Python-3.11%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
8
+ [![JAX](https://img.shields.io/badge/JAX-0.9-000000)](https://docs.jax.dev/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/juannat7/kews/blob/main/LICENSE.txt)
10
+ [![PyPI version](https://img.shields.io/pypi/v/kews)](https://pypi.org/project/kews/)
11
+ [![PyPI downloads](https://img.shields.io/pypi/dm/kews)](https://pypi.org/project/kews/)
12
+ [![arXiv](https://img.shields.io/badge/arXiv-2608.14716-b31b1b.svg)](https://arxiv.org/abs/2608.14716)
13
+
14
+ </div>
15
+
16
+ ## Abstract
17
+
18
+ Abrupt transitions in complex systems are often preceded by early warning signals. However, most indicators rely on the notion of critical slowing down and do not generally extend to rate-induced tipping where transitions can occur without local loss of stability. This is problematic in stochastic, nonautonomous systems where internal variability and time-varying variables interact to shape tipping onset.
19
+
20
+ We use Koopman operator theory to develop a unified early warning framework for both bifurcation and rate-induced tipping in stochastic systems. Our approach builds on residual Koopman mode decomposition that measures discrepancies between dynamics and their finite-dimensional approximation, and extends it to the control setting by augmenting the observable space with time-varying control variables.
21
+
22
+ In idealized examples, the resulting indicators recover expected signatures near bifurcation points and improve detection in rate-induced regimes where classical indicators fail. We further show that learned embeddings through deep learning outperform prescribed dictionaries, especially in a high-dimensional setting.
23
+
24
+ Applied to simulations of the Atlantic Meridional Overturning Circulation, our Koopman-based indicators distinguish tipping from non-tipping trajectories and reveal interpretable spectral signatures prior to critical transition.
25
+
26
+ ## Installation
27
+
28
+ Python 3.11 or newer is required. Install the library from PyPI:
29
+
30
+ ```bash
31
+ pip install kews
32
+ ```
33
+
34
+ To reproduce the paper or develop the code:
35
+
36
+ ```bash
37
+ git clone https://github.com/juannat7/kews.git
38
+ cd kews
39
+ pip install -e ".[paper,dev]"
40
+ ```
41
+
42
+ Reproduction instructions are in [examples](https://github.com/juannat7/kews/tree/main/examples) for the model systems and [experiments](https://github.com/juannat7/kews/tree/main/experiments) for the coupled AMOC and empirical cases.
43
+
44
+ ## Quickstart
45
+
46
+ Compute rolling ResKMD residuals from a scalar time series:
47
+
48
+ ```python
49
+ import jax.numpy as jnp
50
+ from jax import random
51
+
52
+ import kews
53
+ from kews.observables import time_delay
54
+
55
+ time = jnp.linspace(0, 10 * jnp.pi, 100)
56
+ state = jnp.sin(time) + 0.01 * random.normal(random.key(7), time.shape)
57
+
58
+ signal = kews.resdmd(
59
+ state,
60
+ window=50, # Window length in samples (or a fraction, e.g. 0.5)
61
+ observable=time_delay(n_delay=10), # Time-delay dictionary with 10 coordinates
62
+ rank=0.9, # Retain 90% of the SVD energy
63
+ )
64
+
65
+ # One residual per time step; the first 49 entries are NaN.
66
+ print(signal.shape) # (100,)
67
+ ```
68
+
69
+ ## Control-aware residuals
70
+
71
+ Pass a control time series aligned with the state:
72
+
73
+ ```python
74
+ control = jnp.linspace(-1, 1, state.size)
75
+ controlled_signal = kews.resdmd(
76
+ state,
77
+ window=50,
78
+ observable=time_delay(10),
79
+ control=control,
80
+ )
81
+ ```
82
+
83
+ ## Observable choices
84
+
85
+ Use fixed random Fourier features instead of delay coordinates:
86
+
87
+ ```python
88
+ from kews.observables import rff
89
+
90
+ random_signal = kews.resdmd(
91
+ state,
92
+ window=50,
93
+ observable=rff(n_features=100, scale=0.2, seed=7),
94
+ )
95
+ ```
96
+
97
+ The random basis stays fixed across windows. An autoencoder can learn the features:
98
+
99
+ ```python
100
+ from kews.observables import mlp
101
+
102
+ learned_signal = kews.resdmd(
103
+ state,
104
+ window=50,
105
+ observable=mlp(hidden_layers=(16, 8), bottleneck_dim=3, seed=7),
106
+ fit_kwargs={"epochs": 200, "batch_size": 32, "lr": 1e-3},
107
+ )
108
+ ```
109
+
110
+ Training uses only the first window; the encoder is then frozen. Create a new observable for each independent fit. Paper notebooks specify their full training settings.
111
+
112
+ ## Spectral diagnostics
113
+
114
+ ```python
115
+ from kews import diagnostics
116
+
117
+ fit = diagnostics.fit_operator(state, observable=time_delay(10), rank=0.9)
118
+ generator = diagnostics.generator_eigenvalues(fit["eigvals"], dt=1.0)
119
+ dominant = diagnostics.dominant_mode(generator, dt=1.0)
120
+ ```
121
+
122
+ `dt` is the sampling interval in the units of the input data. The mode summary includes decay rate, oscillation period, and e-folding time.
123
+
124
+ ## Citation
125
+
126
+ ```bibtex
127
+ @article{nathaniel2026koopman,
128
+ title={Koopman early warning signals for bifurcation and rate-induced tipping},
129
+ author={Nathaniel, Juan and Roesch, Carla and DeSantis, Derek and Kooloth, Parvathi and Fan, Hang and Lucarini, Valerio and Romanou, Anastasia and Gentine, Pierre},
130
+ journal={arXiv preprint arXiv:2608.14716},
131
+ year={2026}
132
+ }
133
+ ```
134
+
135
+ Code uses the [MIT license](https://github.com/juannat7/kews/blob/main/LICENSE.txt). External datasets retain their original terms.