Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
name: Publish library

permissions: {}

on:
push:
branches:
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
name: Run tests

permissions: {}

on:
pull_request:
push:
Expand All @@ -11,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
python-version: ["3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
Expand Down
8 changes: 3 additions & 5 deletions docs/source/changelog.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# Change Log

## v0.x.x (Unreleased)
### New features

## v0.10.0 (2025 Feb 19)
### Maintenance and fixes

### Documentation
* Remove leftover print in `pinv` {pull}`87`
* Update minimum dependency versions {pull}`88`

## v0.9.1 (2025 June 18)
### Maintenance and fixes
Expand Down
10 changes: 8 additions & 2 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,19 @@ Get started with xarray-einstats
:::

## Similar projects
Here we list some similar projects we know of. Note that all of
them are complementary and don't overlap:
Here we list some similar projects we know of that aim to extend and complement xarray
in specific computations. Note that all of them are complementary and don't overlap:

* [xr-scipy](https://xr-scipy.readthedocs.io/en/latest/index.html)
* [xarray-extras](https://xarray-extras.readthedocs.io/en/latest/)
* [xhistogram](https://xhistogram.readthedocs.io/en/latest/)
* [xrft](https://xrft.readthedocs.io/en/latest/)

There is also a much more comprehensive list of xarray related projects [on xarray's docs](https://docs.xarray.dev/en/stable/user-guide/ecosystem.html).

In addition, there is an [xtensor module](https://pytensor.readthedocs.io/en/latest/library/xtensor/index.html) in PyTensor,
a library for tensor/array operations with symbolic computation elements, with similar dimension based syntax.

## Cite xarray-einstats
If you use this software, please cite it using the following template and the version
specific DOI provided by Zenodo. Click on the badge to go to the Zenodo page
Expand Down
242 changes: 175 additions & 67 deletions docs/source/tutorials/einops-basics-port.ipynb

Large diffs are not rendered by default.

3,380 changes: 2,824 additions & 556 deletions docs/source/tutorials/linalg_tutorial.ipynb

Large diffs are not rendered by default.

1,958 changes: 1,627 additions & 331 deletions docs/source/tutorials/np_linalg_tutorial_port.ipynb

Large diffs are not rendered by default.

2,059 changes: 1,614 additions & 445 deletions docs/source/tutorials/stats_tutorial.ipynb

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions docstub.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[tool.docstub.known_imports]
xarray = {import = "xarray"}
numbers = {import = "numbers"}
[tool.docstub.type_prefixes]
numbers = "numbers"
xarray = "xarray"

# Specify human-friendly aliases that can be used instead of Python-parsable
# annotations.
# TODO rename to qualname_alias or something
[tool.docstub.replace_doctypes]
[tool.docstub.type_nicknames]
sequence = "Sequence"
iterable = "Iterable"
hashable = "Hashable"
iterator = "Iterator"
scalar = "numbers.Number"
Expand Down
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
name = "xarray-einstats"
description = "Stats, linear algebra and einops for xarray"
readme = "README.md"
requires-python = ">=3.11"
requires-python = ">=3.12"
license = {file = "LICENSE"}
authors = [
{name = "ArviZ team", email = "arviz.devs@gmail.com"}
Expand All @@ -27,9 +27,9 @@ classifiers = [
]
dynamic = ["version"]
dependencies = [
"numpy>=1.25",
"scipy>=1.11",
"xarray>=2023.06.0",
"numpy>=2.0",
"scipy>=1.13",
"xarray>=2024.02.0",
]

[tool.flit.module]
Expand All @@ -41,7 +41,7 @@ version = {attr = "xarray_einstats.__version__"}
[project.urls]
source = "https://github.com/arviz-devs/xarray-einstats"
tracker = "https://github.com/arviz-devs/xarray-einstats/issues"
documentation = "https://xarray-einstats.readthedocs.io"
documentation = "https://einstats.python.arviz.org"
funding = "https://opencollective.com/arviz"

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/xarray_einstats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"EinopsAccessor",
]

__version__ = "0.10.0.dev0"
__version__ = "0.10.0"


def sort(da, dim, kind=None, stable=None, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion src/xarray_einstats/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def sort(
stable: bool | None = ...,
**kwargs: Incomplete,
) -> xarray.DataArray: ...
def _remove_indexes_to_reduce(da, dims) -> None: ...
def _remove_indexes_to_reduce(da: Incomplete, dims: Incomplete) -> None: ...
def _find_index(elem: Incomplete, to_search_in: Incomplete) -> None: ...
def _create_ref(
*args: Incomplete, dims: Incomplete, np_creator: Incomplete, dtype: Incomplete = ...
Expand Down
97 changes: 69 additions & 28 deletions src/xarray_einstats/accessors.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# File generated with docstub

import xarray as xr
from _typeshed import Incomplete

from .linalg import (
cholesky,
Expand All @@ -24,36 +25,76 @@ from .linalg import (
)

class LinAlgAccessor:
def __init__(self, xarray_obj) -> None: ...
def matrix_transpose(self, dims) -> None: ...
def matrix_power(self, n, dims=..., **kwargs) -> None: ...
def cholesky(self, dims=..., **kwargs) -> None: ...
def qr(self, dims=..., *, mode=..., out_append=..., **kwargs) -> None: ...
def __init__(self, xarray_obj: Incomplete) -> None: ...
def matrix_transpose(self, dims: Incomplete) -> None: ...
def matrix_power(self, n: Incomplete, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def cholesky(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def qr(
self,
dims: Incomplete = ...,
*,
mode: Incomplete = ...,
out_append: Incomplete = ...,
**kwargs: Incomplete,
) -> None: ...
def svd(
self,
dims=...,
dims: Incomplete = ...,
*,
full_matrices: Incomplete = ...,
compute_uv: Incomplete = ...,
hermitian: Incomplete = ...,
out_append: Incomplete = ...,
**kwargs: Incomplete,
) -> None: ...
def eig(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def eigh(
self, dims: Incomplete = ..., *, UPLO: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def eigvals(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def eigvalsh(
self, dims: Incomplete = ..., *, UPLO: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def norm(
self, dims: Incomplete = ..., *, ord: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def cond(
self, dims: Incomplete = ..., *, p: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def det(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def matrix_rank(
self,
dims: Incomplete = ...,
*,
full_matrices=...,
compute_uv=...,
hermitian=...,
out_append=...,
**kwargs,
) -> None: ...
def eig(self, dims=..., **kwargs) -> None: ...
def eigh(self, dims=..., *, UPLO=..., **kwargs) -> None: ...
def eigvals(self, dims=..., **kwargs) -> None: ...
def eigvalsh(self, dims=..., *, UPLO=..., **kwargs) -> None: ...
def norm(self, dims=..., *, ord=..., **kwargs) -> None: ...
def cond(self, dims=..., *, p=..., **kwargs) -> None: ...
def det(self, dims=..., **kwargs) -> None: ...
def matrix_rank(self, dims=..., *, tol=..., hermitian=..., **kwargs) -> None: ...
def slogdet(self, dims=..., **kwargs) -> None: ...
def trace(self, dims=..., *, offset=..., dtype=..., out=..., **kwargs) -> None: ...
def diagonal(self, dims=..., *, offset=..., **kwargs) -> None: ...
def solve(self, db, dims=..., **kwargs) -> None: ...
def inv(self, dims=..., **kwargs) -> None: ...
tol: Incomplete = ...,
hermitian: Incomplete = ...,
**kwargs: Incomplete,
) -> None: ...
def slogdet(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def trace(
self,
dims: Incomplete = ...,
*,
offset: Incomplete = ...,
dtype: Incomplete = ...,
out: Incomplete = ...,
**kwargs: Incomplete,
) -> None: ...
def diagonal(
self, dims: Incomplete = ..., *, offset: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def solve(self, db: Incomplete, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...
def inv(self, dims: Incomplete = ..., **kwargs: Incomplete) -> None: ...

class EinopsAccessor:
def __init__(self, xarray_obj) -> None: ...
def rearrange(self, pattern, pattern_in=..., **kwargs) -> None: ...
def reduce(self, pattern, reduction, pattern_in=..., **kwargs) -> None: ...
def __init__(self, xarray_obj: Incomplete) -> None: ...
def rearrange(
self, pattern: Incomplete, pattern_in: Incomplete = ..., **kwargs: Incomplete
) -> None: ...
def reduce(
self,
pattern: Incomplete,
reduction: Incomplete,
pattern_in: Incomplete = ...,
**kwargs: Incomplete,
) -> None: ...
17 changes: 8 additions & 9 deletions src/xarray_einstats/einops.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# File generated with docstub

import warnings
from collections.abc import Callable, Hashable
from collections.abc import Hashable

import einops
import xarray
Expand All @@ -12,9 +11,9 @@ __all__ = ["rearrange", "reduce", "DaskBackend"]

class DimHandler:
def __init__(self) -> None: ...
def get_name(self, dim) -> None: ...
def get_names(self, dim_list) -> None: ...
def rename_kwarg(self, key) -> None: ...
def get_name(self, dim: Incomplete) -> None: ...
def get_names(self, dim_list: Incomplete) -> None: ...
def rename_kwarg(self, key: Incomplete) -> None: ...

def process_pattern_list(
redims: list[Hashable | list | dict],
Expand All @@ -25,7 +24,7 @@ def process_pattern_list(
def translate_pattern(pattern: str) -> list[Hashable | list | dict]: ...
def _rearrange(
da: xarray.DataArray,
out_dims: list[str, list | dict],
out_dims: list[str | list | dict],
in_dims: list[str | dict] | None = ...,
dim_lengths: dict | None = ...,
) -> None: ...
Expand All @@ -38,15 +37,15 @@ def rearrange(
) -> xarray.DataArray: ...
def _reduce(
da: xarray.DataArray,
reduction: str | Callable,
reduction: str | callable,
out_dims: list[str | list | dict],
in_dims: list[str | dict] | None = ...,
dim_lengths: dict[Hashable, int] | None = ...,
) -> None: ...
def reduce(
da: xarray.DataArray,
pattern: str | list[str | list | dict],
reduction: str | Callable,
reduction: str | callable,
pattern_in: list[str | dict] | None = ...,
dim_lengths: dict[Hashable, int] | None = ...,
**dim_lengths_kwargs: int,
Expand All @@ -57,7 +56,7 @@ class DaskBackend(einops._backends.AbstractBackend):
framework_name: Incomplete

def __init__(self) -> None: ...
def is_appropriate_type(self, tensor) -> None: ...
def is_appropriate_type(self, tensor: Incomplete) -> None: ...
def from_numpy(self, x: Incomplete) -> None: ...
def to_numpy(self, x: Incomplete) -> None: ...
def arange(self, start: Incomplete, stop: Incomplete) -> None: ...
Expand Down
Loading