dapper 1.5.0__tar.gz → 1.6.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.
- dapper-1.6.0/PKG-INFO +83 -0
- {dapper-1.5.0 → dapper-1.6.0}/README.md +25 -12
- {dapper-1.5.0 → dapper-1.6.0}/dapper/README.md +4 -4
- {dapper-1.5.0 → dapper-1.6.0}/dapper/__init__.py +2 -2
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/README.md +2 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/baseline.py +6 -6
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/ensemble.py +24 -21
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/extended.py +8 -8
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/other.py +9 -10
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/particle.py +38 -32
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/variational.py +23 -20
- {dapper-1.5.0 → dapper-1.6.0}/dapper/dpr_config.py +2 -4
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LA/__init__.py +5 -3
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/bocquet2012.py +1 -1
- dapper-1.6.0/dapper/mods/Lorenz63/ramgraber2022.py +37 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/anderson2009.py +3 -3
- dapper-1.6.0/dapper/mods/Lorenz96/spantini2019.py +41 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/spectral_obs.py +1 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/todter2015_G.py +1 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96s/__init__.py +2 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/__init__.py +2 -2
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/README.md +36 -32
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/sakov2008.py +35 -28
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/__init__.py +70 -33
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/integration.py +2 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/utils.py +2 -2
- {dapper-1.5.0 → dapper-1.6.0}/dapper/stats.py +2 -5
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/datafiles.py +1 -1
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/liveplotting.py +72 -58
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/localization.py +6 -16
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/matrices.py +11 -2
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/progressbar.py +7 -7
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/randvars.py +14 -14
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/remote/README.md +1 -1
- dapper-1.6.0/dapper/tools/seeding.py +29 -0
- dapper-1.6.0/dapper.egg-info/PKG-INFO +83 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper.egg-info/SOURCES.txt +3 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper.egg-info/requires.txt +1 -1
- {dapper-1.5.0 → dapper-1.6.0}/examples/basic_1.py +5 -7
- {dapper-1.5.0 → dapper-1.6.0}/examples/basic_2.py +2 -2
- {dapper-1.5.0 → dapper-1.6.0}/setup.py +1 -1
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_HMMs.py +20 -21
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_example_2.py +42 -37
- dapper-1.6.0/tests/test_rng.py +22 -0
- dapper-1.5.0/PKG-INFO +0 -29
- dapper-1.5.0/dapper/tools/seeding.py +0 -68
- dapper-1.5.0/dapper.egg-info/PKG-INFO +0 -29
- {dapper-1.5.0 → dapper-1.6.0}/LICENCE.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/da_methods/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/dpr_config.yaml +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/DoublePendulum/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/DoublePendulum/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/DoublePendulum/settings101.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Id/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Ikeda/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Ikeda/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Ikeda/some_settings_01.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/KS/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/KS/bocquet2019.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/KS/compare_schemes.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/KS/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LA/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LA/evensen2009.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LA/raanes2015.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LA/small.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz05/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz05/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz05/settings01.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/anderson2010rhf.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/extras.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/mandel2016.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/sakov2012.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz63/wiljes2017.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz84/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz84/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz84/harder.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz84/pajonk2012.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/bocquet2010.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/bocquet2010_m40.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/bocquet2015loc.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/extras.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/frei2013bridging.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/hoteit2015.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/miyoshi2011.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/pinheiro2019.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/raanes2016.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/sakov2008.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96/todter2015.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/Lorenz96s/grudzien2020.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/illust_LorenzUV.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/illust_parameterizations.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/lorenz96.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LorenzUV/wilks05.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LotkaVolterra/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LotkaVolterra/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/LotkaVolterra/settings101.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/counillon2009.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/Makefile +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/calc.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/data.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/helmholtz.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/interface.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/nfw.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/parameters.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_cou09_ens.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_cou09_truth.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_counillon2009_ens.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_counillon2009_truth.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_sak08.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_sakov2008.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_sample_generation.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/prms_test_model.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/qg.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/qgflux.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/qgstep.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/f90/utils.f90 +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/governing_eqn.png +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/QG/illust_obs.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/README.md +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/VL20/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/VL20/demo.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/mods/explore_props.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/chronos.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/colors.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/linalg.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/multiproc.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/remote/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/remote/autoscaler.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/remote/uplink.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/rounding.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/series.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/tools/viz.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/xp_launch.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper/xp_process.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper.egg-info/dependency_links.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/dapper.egg-info/top_level.txt +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/pyproject.toml +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/setup.cfg +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/__init__.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_TLMs.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_data.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_demos.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_iEnKS.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_localization.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_matrices.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_operator.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_plotting.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_printing.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_randvars.py +0 -0
- {dapper-1.5.0 → dapper-1.6.0}/tests/test_round2.py +0 -0
dapper-1.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: dapper
|
|
3
|
+
Version: 1.6.0
|
|
4
|
+
Summary: DAPPER benchmarks the performance of data assimilation (DA) methods.
|
|
5
|
+
Author: Patrick N. Raanes
|
|
6
|
+
Author-email: patrick.n.raanes@gmail.com
|
|
7
|
+
Project-URL: Documentation, https://nansencenter.github.io/DAPPER/
|
|
8
|
+
Project-URL: Source, https://github.com/nansencenter/DAPPER
|
|
9
|
+
Project-URL: Tracker, https://github.com/nansencenter/DAPPER/issues
|
|
10
|
+
Keywords: data-assimilation enkf kalman-filtering state-estimation particle-filter kalman bayesian-methods bayesian-filter chaos
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENCE.txt
|
|
20
|
+
Requires-Dist: scipy>=1.10
|
|
21
|
+
Requires-Dist: jupyter
|
|
22
|
+
Requires-Dist: ipdb
|
|
23
|
+
Requires-Dist: ipython>=5.1
|
|
24
|
+
Requires-Dist: tornado~=6.3.2
|
|
25
|
+
Requires-Dist: matplotlib~=3.7
|
|
26
|
+
Requires-Dist: mpl-tools==0.2.50
|
|
27
|
+
Requires-Dist: tqdm~=4.31
|
|
28
|
+
Requires-Dist: pyyaml
|
|
29
|
+
Requires-Dist: colorama~=0.4.1
|
|
30
|
+
Requires-Dist: tabulate~=0.8.3
|
|
31
|
+
Requires-Dist: dill==0.3.2
|
|
32
|
+
Requires-Dist: patlib==0.3.5
|
|
33
|
+
Requires-Dist: struct-tools==0.2.5
|
|
34
|
+
Requires-Dist: multiprocessing-on-dill==3.5.0a4
|
|
35
|
+
Requires-Dist: threadpoolctl<4.0.0,>=3.0.0
|
|
36
|
+
Provides-Extra: qt
|
|
37
|
+
Requires-Dist: PyQt5; extra == "qt"
|
|
38
|
+
Requires-Dist: qtpy; extra == "qt"
|
|
39
|
+
Provides-Extra: debug
|
|
40
|
+
Requires-Dist: line_profiler; extra == "debug"
|
|
41
|
+
Requires-Dist: pre-commit; extra == "debug"
|
|
42
|
+
Requires-Dist: pdbpp>=0.10.3; extra == "debug"
|
|
43
|
+
Provides-Extra: test
|
|
44
|
+
Requires-Dist: tox; extra == "test"
|
|
45
|
+
Requires-Dist: coverage>=5.1; extra == "test"
|
|
46
|
+
Requires-Dist: pytest; extra == "test"
|
|
47
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
48
|
+
Requires-Dist: pytest-sugar; extra == "test"
|
|
49
|
+
Requires-Dist: pytest-benchmark; extra == "test"
|
|
50
|
+
Requires-Dist: pytest-clarity; extra == "test"
|
|
51
|
+
Requires-Dist: pytest-xdist; extra == "test"
|
|
52
|
+
Requires-Dist: pytest-timeout; extra == "test"
|
|
53
|
+
Provides-Extra: lint
|
|
54
|
+
Requires-Dist: flake8<5; extra == "lint"
|
|
55
|
+
Requires-Dist: flakeheaven; extra == "lint"
|
|
56
|
+
Requires-Dist: autopep8; extra == "lint"
|
|
57
|
+
Provides-Extra: build
|
|
58
|
+
Requires-Dist: twine; extra == "build"
|
|
59
|
+
Requires-Dist: pdoc; extra == "build"
|
|
60
|
+
Requires-Dist: jupytext; extra == "build"
|
|
61
|
+
Provides-Extra: dev
|
|
62
|
+
Requires-Dist: line_profiler; extra == "dev"
|
|
63
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
64
|
+
Requires-Dist: pdbpp>=0.10.3; extra == "dev"
|
|
65
|
+
Requires-Dist: tox; extra == "dev"
|
|
66
|
+
Requires-Dist: coverage>=5.1; extra == "dev"
|
|
67
|
+
Requires-Dist: pytest; extra == "dev"
|
|
68
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
69
|
+
Requires-Dist: pytest-sugar; extra == "dev"
|
|
70
|
+
Requires-Dist: pytest-benchmark; extra == "dev"
|
|
71
|
+
Requires-Dist: pytest-clarity; extra == "dev"
|
|
72
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
73
|
+
Requires-Dist: pytest-timeout; extra == "dev"
|
|
74
|
+
Requires-Dist: flake8<5; extra == "dev"
|
|
75
|
+
Requires-Dist: flakeheaven; extra == "dev"
|
|
76
|
+
Requires-Dist: autopep8; extra == "dev"
|
|
77
|
+
Requires-Dist: twine; extra == "dev"
|
|
78
|
+
Requires-Dist: pdoc; extra == "dev"
|
|
79
|
+
Requires-Dist: jupytext; extra == "dev"
|
|
80
|
+
|
|
81
|
+
It is usually best to install from source (github),
|
|
82
|
+
so that you the code is readily available to play with.
|
|
83
|
+
See full README on [github](https://github.com/nansencenter/DAPPER).
|
|
@@ -10,10 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
<img src="/docs/imgs/logo_wtxt.png" align="left" width="250"/>
|
|
12
12
|
|
|
13
|
-
DAPPER is a set of templates for **benchmarking** the performance of
|
|
14
|
-
|
|
15
|
-
The tests provide experimental support and guidance for
|
|
16
|
-
new developments in DA.
|
|
13
|
+
DAPPER is a set of templates for **benchmarking** the performance of **data assimilation** (DA) methods.
|
|
14
|
+
The numerical experiments provide support and guidance for new developments in DA.
|
|
17
15
|
The typical set-up is a **synthetic (twin) experiment**, where you
|
|
18
16
|
specify a dynamic model and an observational model,
|
|
19
17
|
and use these to generate a synthetic truth (multivariate time series),
|
|
@@ -38,8 +36,8 @@ The [documentation](https://nansencenter.github.io/DAPPER)
|
|
|
38
36
|
includes general guidelines and the API,
|
|
39
37
|
but for any serious use you will want to read and adapt the code yourself.
|
|
40
38
|
If you use it in a publication, please cite, e.g.,
|
|
41
|
-
*The experiments used (inspiration from) DAPPER [ref], version 1.
|
|
42
|
-
where [ref] points to [ DAPPER [ref], version 1.6.0*,
|
|
40
|
+
where [ref] points to [](https://doi.org/10.5281/zenodo.10710355).
|
|
43
41
|
Lastly, for an introduction to DA theory also using Python,
|
|
44
42
|
see these [tutorials](https://github.com/nansencenter/DA-tutorials).
|
|
45
43
|
|
|
@@ -128,7 +126,7 @@ Ensure the printed version is 3.9 or more.
|
|
|
128
126
|
- If the script comes with a `requirements.txt` file, then do
|
|
129
127
|
`pip install -r path/to/requirements.txt`.
|
|
130
128
|
- If not, hopefully you know the version of DAPPER needed. Run
|
|
131
|
-
`pip install dapper==1.
|
|
129
|
+
`pip install dapper==1.5.1` to get version `1.5.1` (as an example).
|
|
132
130
|
|
|
133
131
|
#### *Finally*: Test the installation
|
|
134
132
|
|
|
@@ -233,9 +231,7 @@ DAPPER is aimed at research and teaching (see discussion up top).
|
|
|
233
231
|
Example of limitations:
|
|
234
232
|
|
|
235
233
|
- It is not suited for very big models (>60k unknowns).
|
|
236
|
-
-
|
|
237
|
-
(although the `Dyn` and `Obs` models may otherwise be time-dependent).
|
|
238
|
-
- Non-uniform time sequences not fully supported.
|
|
234
|
+
- Non-uniform time sequences.
|
|
239
235
|
|
|
240
236
|
The scope of DAPPER is restricted because
|
|
241
237
|
|
|
@@ -321,7 +317,24 @@ in the development of DAPPER.
|
|
|
321
317
|
[26]: https://github.com/CliMA/EnsembleKalmanProcesses.jl
|
|
322
318
|
|
|
323
319
|
|
|
324
|
-
##
|
|
320
|
+
## Contributing
|
|
321
|
+
|
|
322
|
+
### Issues and Pull requests
|
|
323
|
+
|
|
324
|
+
Do not hesitate to open an issue, whether to report a problem or ask a question.
|
|
325
|
+
It may take some time for us to get back to you,
|
|
326
|
+
since DAPPER is primarily a volunteer effort.
|
|
327
|
+
Please start by perusing the [documentation](https://nansencenter.github.io/DAPPER/dapper.html)
|
|
328
|
+
and searching the issue tracker for similar items.
|
|
329
|
+
|
|
330
|
+
Pull requests are very welcome.
|
|
331
|
+
Examples: adding a new DA method, dynamical models,
|
|
332
|
+
experimental configuration reproducing literature results,
|
|
333
|
+
or improving the features and capabilities of DAPPER.
|
|
334
|
+
Please keep in mind the intentional [limitations](https://github.com/nansencenter/DAPPER#similar-projects)
|
|
335
|
+
and read the [developers guidelines](https://nansencenter.github.io/DAPPER/dev_guide).
|
|
336
|
+
|
|
337
|
+
### Contributors
|
|
325
338
|
|
|
326
339
|
Patrick N. Raanes,
|
|
327
340
|
Yumeng Chen,
|
|
@@ -345,7 +358,7 @@ and the Center for Western Weather and Water Extremes (CW3E).
|
|
|
345
358
|
<img src="./docs/imgs/CW3E-Logo-Horizontal-FullColor.png?raw=true" width="400">
|
|
346
359
|
<!-- markdownlint-restore -->
|
|
347
360
|
|
|
348
|
-
##
|
|
361
|
+
## Publications
|
|
349
362
|
|
|
350
363
|
- [Combining data assimilation and machine learning to emulate a dynamical model from sparse and noisy observations: A case study with the Lorenz 96 model](https://doi.org/10.1016/j.jocs.2020.101171)
|
|
351
364
|
- [Adaptive covariance inflation in the ensemble Kalman filter by Gaussian scale mixtures](https://doi.org/10.1002/qj.3386)
|
|
@@ -5,11 +5,11 @@ the docs for the various modules.
|
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
8
|
-
See [README/Installation](https://github.com/nansencenter/DAPPER#
|
|
8
|
+
See [README/Installation](https://github.com/nansencenter/DAPPER#installation)
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
|
-
See [README/Getting-started](https://github.com/nansencenter/DAPPER#
|
|
12
|
+
See [README/Getting-started](https://github.com/nansencenter/DAPPER#getting-started)
|
|
13
13
|
|
|
14
14
|
##### Examples
|
|
15
15
|
|
|
@@ -26,8 +26,8 @@ your own **model** or **method**, then
|
|
|
26
26
|
rather than trying to squeeze everything into its templates.
|
|
27
27
|
- If it is relatively simple, however, you may well want to use DAPPER.
|
|
28
28
|
In that case, read this:
|
|
29
|
-
- `mods`
|
|
30
|
-
- `da_methods`
|
|
29
|
+
- `dapper.mods`
|
|
30
|
+
- `dapper.da_methods`
|
|
31
31
|
|
|
32
32
|
Since the generality of DAPPER is
|
|
33
33
|
[limited](https://github.com/nansencenter/DAPPER#similar-projects)
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
.. include:: ./README.md
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
__version__ = "1.
|
|
7
|
+
__version__ = "1.6.0"
|
|
8
8
|
|
|
9
9
|
# A parsimonious list of imports used in the examples
|
|
10
10
|
from .dpr_config import rc
|
|
11
11
|
from .tools.datafiles import find_latest_run, load_xps
|
|
12
12
|
from .tools.rounding import round2sigfig
|
|
13
|
-
from .tools.seeding import set_seed
|
|
13
|
+
from .tools.seeding import rng, set_seed
|
|
14
14
|
from .xp_launch import combinator, seed_and_simulate, xpList
|
|
15
15
|
from .xp_process import xpSpace
|
|
@@ -68,9 +68,9 @@ class OptInterp:
|
|
|
68
68
|
self.stats.assess(k, ko, 'f', mu=muC, Cov=PC)
|
|
69
69
|
|
|
70
70
|
# Analysis
|
|
71
|
-
H = HMM.Obs.linear(muC
|
|
72
|
-
KG = mrdiv(PC@H.T, H@PC@H.T + HMM.Obs.noise.C.full)
|
|
73
|
-
mu = muC + KG@(yy[ko] - HMM.Obs(muC
|
|
71
|
+
H = HMM.Obs(ko).linear(muC)
|
|
72
|
+
KG = mrdiv(PC@H.T, H@PC@H.T + HMM.Obs(ko).noise.C.full)
|
|
73
|
+
mu = muC + KG@(yy[ko] - HMM.Obs(ko)(muC))
|
|
74
74
|
|
|
75
75
|
P = (Id - KG@H) @ PC
|
|
76
76
|
SM = fit_sigmoid(P.trace()/PC.trace(), L, k)
|
|
@@ -123,9 +123,9 @@ class Var3D:
|
|
|
123
123
|
self.stats.assess(k, ko, 'f', mu=mu, Cov=P)
|
|
124
124
|
|
|
125
125
|
# Analysis
|
|
126
|
-
H = HMM.Obs.linear(mu
|
|
127
|
-
KG = mrdiv(B@H.T, H@B@H.T + HMM.Obs.noise.C.full)
|
|
128
|
-
mu = mu + KG@(yy[ko] - HMM.Obs(mu
|
|
126
|
+
H = HMM.Obs(ko).linear(mu)
|
|
127
|
+
KG = mrdiv(B@H.T, H@B@H.T + HMM.Obs(ko).noise.C.full)
|
|
128
|
+
mu = mu + KG@(yy[ko] - HMM.Obs(ko)(mu))
|
|
129
129
|
|
|
130
130
|
# Re-calibrate fit_sigmoid with new W0 = Pa/B
|
|
131
131
|
P = (Id - KG@H) @ B
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""The EnKF and other ensemble-based methods."""
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
import numpy.random as rnd
|
|
5
4
|
import scipy.linalg as sla
|
|
6
5
|
from numpy import diag, eye, sqrt, zeros
|
|
7
6
|
|
|
@@ -11,6 +10,7 @@ from dapper.tools.linalg import mldiv, mrdiv, pad0, svd0, svdi, tinv, tsvd
|
|
|
11
10
|
from dapper.tools.matrices import funm_psd, genOG_1
|
|
12
11
|
from dapper.tools.progressbar import progbar
|
|
13
12
|
from dapper.tools.randvars import GaussRV
|
|
13
|
+
from dapper.tools.seeding import rng
|
|
14
14
|
|
|
15
15
|
from . import da_method
|
|
16
16
|
|
|
@@ -47,7 +47,7 @@ class EnKF:
|
|
|
47
47
|
# Analysis update
|
|
48
48
|
if ko is not None:
|
|
49
49
|
self.stats.assess(k, ko, 'f', E=E)
|
|
50
|
-
E = EnKF_analysis(E, HMM.Obs(E
|
|
50
|
+
E = EnKF_analysis(E, HMM.Obs(ko)(E), HMM.Obs(ko).noise, yy[ko],
|
|
51
51
|
self.upd_a, self.stats, ko)
|
|
52
52
|
E = post_process(E, self.infl, self.rot)
|
|
53
53
|
|
|
@@ -161,10 +161,10 @@ def EnKF_analysis(E, Eo, hnoise, y, upd_a, stats=None, ko=None):
|
|
|
161
161
|
v = v - mult[0]*Yj # noqa
|
|
162
162
|
v /= sqrt(v@v)
|
|
163
163
|
Zj = v*sqrt(N1) # Standardized perturbation along v
|
|
164
|
-
Zj *= np.sign(
|
|
164
|
+
Zj *= np.sign(rng.standard_normal() - 0.5) # Random sign
|
|
165
165
|
else:
|
|
166
166
|
# The usual stochastic perturbations.
|
|
167
|
-
Zj = mean0(
|
|
167
|
+
Zj = mean0(rng.standard_normal(N)) # Un-coloured noise
|
|
168
168
|
if 'Var1' in upd_a:
|
|
169
169
|
Zj *= sqrt(N/(Zj@Zj))
|
|
170
170
|
|
|
@@ -319,7 +319,7 @@ def add_noise(E, dt, noise, method):
|
|
|
319
319
|
E, _, Qa12 = sqrt_core()
|
|
320
320
|
if N <= Nx:
|
|
321
321
|
Z = Q12 - A.T@Qa12
|
|
322
|
-
E += sqrt(dt)*(Z@
|
|
322
|
+
E += sqrt(dt)*(Z@rng.standard_normal((Z.shape[1], N))).T
|
|
323
323
|
|
|
324
324
|
elif method == 'Sqrt-Dep':
|
|
325
325
|
E, T, Qa12 = sqrt_core()
|
|
@@ -334,7 +334,7 @@ def add_noise(E, dt, noise, method):
|
|
|
334
334
|
Z = Q12 - Q_hat12
|
|
335
335
|
D_hat = A.T@(T-eye(N))
|
|
336
336
|
Xi_hat = Q_hat12_inv @ D_hat
|
|
337
|
-
Xi_til = (eye(rQ) - Q_hat12_proj)@
|
|
337
|
+
Xi_til = (eye(rQ) - Q_hat12_proj)@rng.standard_normal((rQ, N))
|
|
338
338
|
D_til = Z@(Xi_hat + sqrt(dt)*Xi_til)
|
|
339
339
|
E += D_til.T
|
|
340
340
|
|
|
@@ -382,7 +382,7 @@ class EnKS:
|
|
|
382
382
|
if ko is not None:
|
|
383
383
|
self.stats.assess(k, ko, 'f', E=E[k])
|
|
384
384
|
|
|
385
|
-
Eo = HMM.Obs(E[k]
|
|
385
|
+
Eo = HMM.Obs(ko)(E[k])
|
|
386
386
|
y = yy[ko]
|
|
387
387
|
|
|
388
388
|
# Inds within Lag
|
|
@@ -391,7 +391,7 @@ class EnKS:
|
|
|
391
391
|
EE = E[kk]
|
|
392
392
|
|
|
393
393
|
EE = self.reshape_to(EE)
|
|
394
|
-
EE = EnKF_analysis(EE, Eo, HMM.Obs.noise, y,
|
|
394
|
+
EE = EnKF_analysis(EE, Eo, HMM.Obs(ko).noise, y,
|
|
395
395
|
self.upd_a, self.stats, ko)
|
|
396
396
|
E[kk] = self.reshape_fr(EE, HMM.Dyn.M)
|
|
397
397
|
E[k] = post_process(E[k], self.infl, self.rot)
|
|
@@ -427,9 +427,9 @@ class EnRTS:
|
|
|
427
427
|
|
|
428
428
|
if ko is not None:
|
|
429
429
|
self.stats.assess(k, ko, 'f', E=E[k])
|
|
430
|
-
Eo = HMM.Obs(E[k]
|
|
430
|
+
Eo = HMM.Obs(ko)(E[k])
|
|
431
431
|
y = yy[ko]
|
|
432
|
-
E[k] = EnKF_analysis(E[k], Eo, HMM.Obs.noise, y,
|
|
432
|
+
E[k] = EnKF_analysis(E[k], Eo, HMM.Obs(ko).noise, y,
|
|
433
433
|
self.upd_a, self.stats, ko)
|
|
434
434
|
E[k] = post_process(E[k], self.infl, self.rot)
|
|
435
435
|
self.stats.assess(k, ko, 'a', E=E[k])
|
|
@@ -468,7 +468,7 @@ def serial_inds(upd_a, y, cvR, A):
|
|
|
468
468
|
dC = np.sum(A*A, 0)/(N-1)
|
|
469
469
|
inds = np.argsort(dC)
|
|
470
470
|
else: # Default: random ordering
|
|
471
|
-
inds =
|
|
471
|
+
inds = rng.permutation(len(y))
|
|
472
472
|
return inds
|
|
473
473
|
|
|
474
474
|
|
|
@@ -492,8 +492,6 @@ class SL_EAKF:
|
|
|
492
492
|
|
|
493
493
|
def assimilate(self, HMM, xx, yy):
|
|
494
494
|
N1 = self.N-1
|
|
495
|
-
R = HMM.Obs.noise
|
|
496
|
-
Rm12 = HMM.Obs.noise.C.sym_sqrt_inv
|
|
497
495
|
|
|
498
496
|
E = HMM.X0.sample(self.N)
|
|
499
497
|
self.stats.assess(0, E=E)
|
|
@@ -504,14 +502,17 @@ class SL_EAKF:
|
|
|
504
502
|
|
|
505
503
|
if ko is not None:
|
|
506
504
|
self.stats.assess(k, ko, 'f', E=E)
|
|
505
|
+
Obs = HMM.Obs(ko)
|
|
506
|
+
R = Obs.noise
|
|
507
507
|
y = yy[ko]
|
|
508
508
|
inds = serial_inds(self.ordr, y, R, center(E)[0])
|
|
509
|
+
Rm12 = Obs.noise.C.sym_sqrt_inv
|
|
509
510
|
|
|
510
|
-
state_taperer =
|
|
511
|
+
state_taperer = Obs.localizer(self.loc_rad, 'y2x', self.taper)
|
|
511
512
|
for j in inds:
|
|
512
513
|
# Prep:
|
|
513
514
|
# ------------------------------------------------------
|
|
514
|
-
Eo =
|
|
515
|
+
Eo = Obs(E)
|
|
515
516
|
xo = np.mean(Eo, 0)
|
|
516
517
|
Y = Eo - xo
|
|
517
518
|
mu = np.mean(E, 0)
|
|
@@ -632,8 +633,9 @@ class LETKF:
|
|
|
632
633
|
|
|
633
634
|
if ko is not None:
|
|
634
635
|
self.stats.assess(k, ko, 'f', E=E)
|
|
635
|
-
|
|
636
|
-
|
|
636
|
+
Obs = HMM.Obs(ko)
|
|
637
|
+
batch, taper = Obs.localizer(self.loc_rad, 'x2y', self.taper)
|
|
638
|
+
E, stats = local_analyses(E, Obs(E), Obs.noise.C, yy[ko],
|
|
637
639
|
batch, taper, pool.map, self.xN, self.g)
|
|
638
640
|
self.stats.write(stats, k, ko, "a")
|
|
639
641
|
E = post_process(E, self.infl, self.rot)
|
|
@@ -851,7 +853,7 @@ class EnKF_N:
|
|
|
851
853
|
g: int = 0
|
|
852
854
|
|
|
853
855
|
def assimilate(self, HMM, xx, yy):
|
|
854
|
-
|
|
856
|
+
N, N1 = self.N, self.N-1
|
|
855
857
|
|
|
856
858
|
# Init
|
|
857
859
|
E = HMM.X0.sample(N)
|
|
@@ -866,7 +868,7 @@ class EnKF_N:
|
|
|
866
868
|
# Analysis
|
|
867
869
|
if ko is not None:
|
|
868
870
|
self.stats.assess(k, ko, 'f', E=E)
|
|
869
|
-
Eo = HMM.Obs(E
|
|
871
|
+
Eo = HMM.Obs(ko)(E)
|
|
870
872
|
y = yy[ko]
|
|
871
873
|
|
|
872
874
|
mu = np.mean(E, 0)
|
|
@@ -876,6 +878,7 @@ class EnKF_N:
|
|
|
876
878
|
Y = Eo-xo
|
|
877
879
|
dy = y - xo
|
|
878
880
|
|
|
881
|
+
R = HMM.Obs(ko).noise.C
|
|
879
882
|
V, s, UT = svd0(Y @ R.sym_sqrt_inv.T)
|
|
880
883
|
du = UT @ (dy @ R.sym_sqrt_inv.T)
|
|
881
884
|
def dgn_N(l1): return pad0((l1*s)**2, N) + N1
|
|
@@ -887,7 +890,7 @@ class EnKF_N:
|
|
|
887
890
|
|
|
888
891
|
if self.dual:
|
|
889
892
|
# Make dual cost function (in terms of l1)
|
|
890
|
-
def pad_rk(arr): return pad0(arr, min(N,
|
|
893
|
+
def pad_rk(arr): return pad0(arr, min(N, len(y)))
|
|
891
894
|
def dgn_rk(l1): return pad_rk((l1*s)**2) + N1
|
|
892
895
|
|
|
893
896
|
def J(l1):
|
|
@@ -962,6 +965,6 @@ class EnKF_N:
|
|
|
962
965
|
E = post_process(E, self.infl, self.rot)
|
|
963
966
|
|
|
964
967
|
self.stats.infl[ko] = l1
|
|
965
|
-
self.stats.trHK[ko] = (((l1*s)**2 + N1)**(-1.0)*s**2).sum()/
|
|
968
|
+
self.stats.trHK[ko] = (((l1*s)**2 + N1)**(-1.0)*s**2).sum()/len(y)
|
|
966
969
|
|
|
967
970
|
self.stats.assess(k, ko, E=E)
|
|
@@ -25,7 +25,6 @@ class ExtKF:
|
|
|
25
25
|
infl: float = 1.0
|
|
26
26
|
|
|
27
27
|
def assimilate(self, HMM, xx, yy):
|
|
28
|
-
R = HMM.Obs.noise.C.full
|
|
29
28
|
Q = 0 if HMM.Dyn.noise.C == 0 else HMM.Dyn.noise.C.full
|
|
30
29
|
|
|
31
30
|
mu = HMM.X0.mu
|
|
@@ -44,10 +43,11 @@ class ExtKF:
|
|
|
44
43
|
|
|
45
44
|
if ko is not None:
|
|
46
45
|
self.stats.assess(k, ko, 'f', mu=mu, Cov=P)
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
Obs = HMM.Obs(ko)
|
|
47
|
+
H = Obs.linear(mu)
|
|
48
|
+
KG = mrdiv(P @ H.T, H@P@H.T + Obs.noise.C.full)
|
|
49
49
|
y = yy[ko]
|
|
50
|
-
mu = mu + KG@(y -
|
|
50
|
+
mu = mu + KG@(y - Obs(mu))
|
|
51
51
|
KH = KG@H
|
|
52
52
|
P = (np.eye(HMM.Dyn.M) - KH) @ P
|
|
53
53
|
|
|
@@ -67,7 +67,6 @@ class ExtRTS:
|
|
|
67
67
|
def assimilate(self, HMM, xx, yy):
|
|
68
68
|
Nx = HMM.Dyn.M
|
|
69
69
|
|
|
70
|
-
R = HMM.Obs.noise.C.full
|
|
71
70
|
Q = 0 if HMM.Dyn.noise.C == 0 else HMM.Dyn.noise.C.full
|
|
72
71
|
|
|
73
72
|
mu = np.zeros((HMM.tseq.K+1, Nx))
|
|
@@ -96,10 +95,11 @@ class ExtRTS:
|
|
|
96
95
|
|
|
97
96
|
if ko is not None:
|
|
98
97
|
self.stats.assess(k, ko, 'f', mu=mu[k], Cov=P[k])
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
Obs = HMM.Obs(ko)
|
|
99
|
+
H = Obs.linear(mu[k])
|
|
100
|
+
KG = mrdiv(P[k] @ H.T, H@P[k]@H.T + Obs.noise.C.full)
|
|
101
101
|
y = yy[ko]
|
|
102
|
-
mu[k] = mu[k] + KG@(y -
|
|
102
|
+
mu[k] = mu[k] + KG@(y - Obs(mu[k]))
|
|
103
103
|
KH = KG@H
|
|
104
104
|
P[k] = (np.eye(Nx) - KH) @ P[k]
|
|
105
105
|
self.stats.assess(k, ko, 'a', mu=mu[k], Cov=P[k])
|
|
@@ -31,9 +31,6 @@ class RHF:
|
|
|
31
31
|
step = 1/N
|
|
32
32
|
cdf_grid = np.linspace(step/2, 1-step/2, N)
|
|
33
33
|
|
|
34
|
-
R = Obs.noise
|
|
35
|
-
Rm12 = Obs.noise.C.sym_sqrt_inv
|
|
36
|
-
|
|
37
34
|
E = X0.sample(N)
|
|
38
35
|
stats.assess(0, E=E)
|
|
39
36
|
|
|
@@ -43,11 +40,13 @@ class RHF:
|
|
|
43
40
|
|
|
44
41
|
if ko is not None:
|
|
45
42
|
stats.assess(k, ko, 'f', E=E)
|
|
43
|
+
Obs = HMM.Obs(ko)
|
|
44
|
+
Rm12 = Obs.noise.C.sym_sqrt_inv
|
|
46
45
|
y = yy[ko]
|
|
47
|
-
inds = serial_inds(self.ordr, y,
|
|
46
|
+
inds = serial_inds(self.ordr, y, Obs.noise.C, center(E)[0])
|
|
48
47
|
|
|
49
48
|
for _, j in enumerate(inds):
|
|
50
|
-
Eo = Obs(E
|
|
49
|
+
Eo = Obs(E)
|
|
51
50
|
xo = np.mean(Eo, 0)
|
|
52
51
|
Y = Eo - xo
|
|
53
52
|
mu = np.mean(E, 0)
|
|
@@ -92,8 +91,7 @@ class LNETF:
|
|
|
92
91
|
Rs: float = 1.0
|
|
93
92
|
|
|
94
93
|
def assimilate(self, HMM, xx, yy):
|
|
95
|
-
Dyn,
|
|
96
|
-
Rm12 = Obs.noise.C.sym_sqrt_inv
|
|
94
|
+
Dyn, tseq, X0, stats = HMM.Dyn, HMM.tseq, HMM.X0, self.stats
|
|
97
95
|
|
|
98
96
|
E = X0.sample(self.N)
|
|
99
97
|
stats.assess(0, E=E)
|
|
@@ -107,10 +105,11 @@ class LNETF:
|
|
|
107
105
|
mu = np.mean(E, 0)
|
|
108
106
|
A = E - mu
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
Obs = HMM.Obs(ko)
|
|
109
|
+
Eo = Obs(E)
|
|
111
110
|
xo = np.mean(Eo, 0)
|
|
112
|
-
YR = (Eo-xo) @
|
|
113
|
-
yR = (yy[ko] - xo) @
|
|
111
|
+
YR = (Eo-xo) @ Obs.noise.C.sym_sqrt_inv.T
|
|
112
|
+
yR = (yy[ko] - xo) @ Obs.noise.C.sym_sqrt_inv.T
|
|
114
113
|
|
|
115
114
|
state_batches, obs_taperer = Obs.localizer(
|
|
116
115
|
self.loc_rad, 'x2y', t, self.taper)
|