Skip to content

Commit

Permalink
Merge pull request #27 from pastas/dev
Browse files Browse the repository at this point in the history
Metran release 0.4.0
  • Loading branch information
martinvonk authored Feb 20, 2024
2 parents d8aef35 + df1548f commit f990839
Show file tree
Hide file tree
Showing 12 changed files with 730 additions and 450 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: metran
name: CI

on:
- push
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/ci_notebooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI NB

on:
pull_request:
branches:
- main

jobs:
test:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: Test suite for notebooks
python: "3.10"
toxenv: notebooks
env:
# Color Output
# Rich (pip)
FORCE_COLOR: 1
# Tox
PY_COLORS: 1
# Pytest
PYTEST_ADDOPTS: "--color=yes"
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
check-latest: true
cache: "pip"
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Setup tox environment
run: tox -e ${{ matrix.toxenv }} --notest

- name: Test
run: tox -e ${{ matrix.toxenv }} --skip-pkg-install
12 changes: 8 additions & 4 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
# Required
version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.9"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
Expand All @@ -14,10 +20,8 @@ formats: all

# Optionally set the version of Python and requirements required to build your docs
python:
version: "3.8"
install:
- method: pip
path: .

build:
image: latest
extra_requirements:
- rtd
5 changes: 0 additions & 5 deletions docs/requirements.txt

This file was deleted.

141 changes: 62 additions & 79 deletions examples/dynamic_factor_model.ipynb

Large diffs are not rendered by default.

455 changes: 220 additions & 235 deletions examples/metran_practical_example.ipynb

Large diffs are not rendered by default.

426 changes: 313 additions & 113 deletions examples/pastas_metran_example.ipynb

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions metran/metran.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def _phi(self, alpha):
float
autoregressive model parameter
"""
a = to_offset(self.settings["freq"]).delta / Timedelta(1, "D")
a = Timedelta(to_offset(self.settings["freq"])) / Timedelta(1, "D")
return np.exp(-a / alpha)

def get_transition_matrix(self, p=None, initial=False):
Expand Down Expand Up @@ -443,7 +443,7 @@ def set_init_parameters(self):
-------
None
"""
pinit_alpha = 10
pinit_alpha = 10.0
for n in range(self.nfactors):
self.parameters.loc["cdf" + str(n + 1) + "_alpha"] = (
pinit_alpha,
Expand Down Expand Up @@ -1111,12 +1111,15 @@ def fit_report(self, output="full"):
"": "",
}

parameters = self.parameters.loc[:, ["optimal", "stderr", "initial", "vary"]]
parameters = self.parameters.loc[
:, ["optimal", "stderr", "initial", "vary"]
].copy()
stderr = parameters.loc[:, "stderr"] / parameters.loc[:, "optimal"]
parameters.loc[:, "stderr"] = "-"
parameters["stderr"] = "-"
parameters.loc[parameters["vary"], "stderr"] = stderr.abs().apply(
"\u00B1{:.2%}".format
)
parameters["initial"] = parameters["initial"].astype(str)
parameters.loc[~parameters["vary"].astype(bool), "initial"] = "-"

# Determine the width of the fit_report based on the parameters
Expand All @@ -1142,8 +1145,7 @@ def fit_report(self, output="full"):

# Create the parameters block
parameters = (
"\nParameters ({n_param} were optimized)\n{line}\n"
"{parameters}".format(
"\nParameters ({n_param} were optimized)\n{line}\n{parameters}".format(
n_param=parameters.vary.sum(),
line=string.format("", fill="=", align=">", width=width),
parameters=parameters,
Expand Down
6 changes: 3 additions & 3 deletions metran/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ def _nearPSD(A, epsilon=0):
val = np.array(np.maximum(eigval, epsilon))
vec = np.array(eigvec)
with np.errstate(divide="ignore", invalid="ignore"):
T = 1 / (np.multiply(vec, vec) * val.T)
T = 1 / (vec**2 @ val.T)
T = np.array(np.sqrt(np.diag(np.array(T).reshape((n)))))
B = T * vec * np.diag(np.array(np.sqrt(val)).reshape((n)))
out = B * B.T
B = T @ vec * np.diag(np.array(np.sqrt(val)).reshape((n)))
out = B @ B.T
return out


Expand Down
2 changes: 1 addition & 1 deletion metran/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# This is the only location where the version will be written and changed.
# Based on https://packaging.python.org/single_source_version/
__version__ = "0.3.0"
__version__ = "0.4.0"
26 changes: 23 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,20 @@ documentation = "https://metran.readthedocs.io/en/latest/"

[project.optional-dependencies]
solvers = ["lmfit >= 1.0.0"]
dino = ["hydropandas"]
linting = ["flake8"]
formatting = ["black[jupyter]", "isort"]
pytesting = ["pytest", "pytest-cov", "pytest-sugar"]
pytesting = ["pytest", "pytest-cov", "pytest-sugar", "jupyter"]
coveraging = ["coverage"]
rtd = [
"metran[dino]",
"sphinx_rtd_theme",
"Ipython",
"ipykernel",
"nbsphinx",
"nbsphinx_link",
"jupyter",
]
full = ["metran[solvers]"]
dev = ["metran[solvers,linting,pytesting,coveraging]", "tox"]

Expand All @@ -61,6 +71,10 @@ line-length = 88
[tool.isort]
profile = "black"

[tool.pytest.ini_options]
addopts = "--strict-markers --durations=0"
markers = ["notebooks: run notebooks"]

[tool.tox]
legacy_tox_ini = """
[tox]
Expand All @@ -71,7 +85,13 @@ legacy_tox_ini = """
description = run unit tests
extras = pytesting,full
commands =
pytest tests
pytest tests -m "not notebooks"
[testenv:notebooks]
description = run the notebooks
extras = pytesting,full,dino
commands =
pytest tests -m "notebooks"
[testenv:format]
description = run formatters
Expand All @@ -91,7 +111,7 @@ legacy_tox_ini = """
[testenv:coverage]
description = get coverage report xml
basepython = 3.9
extras = coveraging,pytesting,full
extras = coveraging,pytesting,full,dino
commands =
coverage run -m pytest tests
coverage xml
Expand Down
44 changes: 44 additions & 0 deletions tests/test_notebooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
from pathlib import Path

import pytest

pathname = Path("./examples/")
files = pathname.glob("*ipynb")

testdir = pathname / "build"

if testdir.is_dir():
testdir.rmdir()
testdir.mkdir()


@pytest.mark.notebooks
@pytest.mark.parametrize("file", files)
def test_notebook(file) -> None:

cwd = os.getcwd()

os.chdir(pathname)

try:
# run autotest on each notebook
cmd = (
"jupyter "
+ "nbconvert "
+ "--ExecutePreprocessor.timeout=600 "
+ "--to "
+ "notebook "
+ "--execute "
+ '"{}" '.format(file.name)
+ "--output-dir "
+ "{} ".format(testdir)
)
ival = os.system(cmd)
msg = "could not run {}".format(file.name)
assert ival == 0, msg
assert os.path.isfile(os.path.join(testdir, file.name)), msg
except Exception as e:
os.chdir(cwd)
raise Exception(e)
os.chdir(cwd)

0 comments on commit f990839

Please sign in to comment.