Skip to content

Commit 4fc61d7

Browse files
authored
einops accessor (#51)
* homogenize einops API * add accessors * add some docs on accessors * fix about einops docs * make running einops tutorial locally easier * improve docs and update changelog
1 parent 2b92d28 commit 4fc61d7

File tree

20 files changed

+807
-391
lines changed

20 files changed

+807
-391
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
# website: http://jupyter.org/
88

99
.ipynb_checkpoints
10+
.virtual_documents
1011
*/.ipynb_checkpoints/*
12+
*/.virtual_documents/*
1113
pati.ipynb
1214

1315
# IPython

docs/source/api/einops.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
.. automodule:: xarray_einstats.einops
55
```
66

7+
78
```{eval-rst}
89
.. autosummary::
910
:toctree: generated/
1011
1112
rearrange
12-
raw_rearrange
1313
reduce
14-
raw_reduce
1514
```
1615

1716
```{eval-rst}

docs/source/api/linalg.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
:toctree: generated/
1212
1313
einsum
14-
raw_einsum
1514
einsum_path
1615
matmul
1716
linalg.matrix_transpose

docs/source/background/einops.md

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,11 @@ of the elements respectively: `->`, space as delimiter and parenthesis:
2323
dimension order in xarray doesn't matter and there isn't much to be done without knowing
2424
the dimension names.
2525

26-
:::{attention}
27-
We also provide some cruder wrappers with syntax closer to einops.
28-
We are experimenting on trying to find the right spot between being clear,
29-
semantic and flexible yet concise.
30-
31-
These `raw_` wrappers like {func}`xarray_einstats.einops.raw_rearrange`
32-
impose several extra constraints to accepted xarray inputs, in addition
33-
to dimension names being strings.
34-
35-
The example data we are using on this page uses single word alphabetical
36-
dimensions names which allows us to demonstrate both side by side.
37-
:::
26+
However, there are also many cases in which dimension names in xarray will be strings
27+
without any spaces nor parenthesis in them. So similarly to the option of
28+
doing `da.stack(dim=("dim1", "dim2"))` which can't be used for all valid
29+
dimension names but is generally easier to write and less error prone,
30+
`xarray_einstats.einops` also provides two possible syntaxes.
3831

3932
The guiding principle of the einops module is to take the input expressions
4033
in our list of str/list/dict and translate them to valid einops expressions
@@ -45,20 +38,60 @@ and thus support "partial" expressions that cover only the dimensions
4538
that will be modified.
4639

4740
Another important consideration is to take into account that _in xarray_,
48-
dimension names should not matter, hence the constraint of using dicts
41+
dimension order should not matter, hence the constraint of using dicts
4942
on the left side. Imposing this constraint also
5043
makes our job of filling in the "partial" expressions much easier.
5144
We do accept that in the right side as we can generate sensible
5245
default names.
5346

54-
As for the `raw_` wrappers, in order to avoid rewriting the partial
55-
expression filling logic, their behaviour is very simplified:
47+
As for the alternative API, its syntax is much closer to that in einops,
48+
as it is string base, but it does add some extra constraints to the dimension names
49+
that are compatible with it.
50+
51+
To avoid rewriting the partial expression filling logic, their behaviour is very simplified:
5652
1. Split the expression in two if possible using `->`
5753
2. Convert each side to list of str/list/dict following the rules of the complete wrappers
5854
3. Call the complete wrapper
5955

6056
This has an extra and a bit hidden advantage. einops supports
6157
_explicit_ ellipsis but we don't, to us an ellipsis is not writing
6258
the dimension name in the expression. Therefore, `.` are valid
63-
in our `raw_` expressions, we convert those to "full xarray" expressions
59+
in our string expressions, we convert those to "full xarray" expressions
6460
which support everything and we don't need extra logic to handle dots either.
61+
62+
## Examples
63+
64+
Given a {class}`~xarray.DataArray` `da` with dimensions `a`, `b`, `c` and `d`,
65+
the table below shows the result of equivalent expressions
66+
and the dimensions (and order) present in their output:
67+
68+
```python
69+
# list syntax
70+
rearrange(da, ["c", "d", "a", "b"])
71+
# string syntax
72+
rearrange(da, "c d a b")
73+
# dims in output: `c`, `d`, `a`, `b`
74+
75+
# ----------------------------
76+
77+
# list syntax
78+
rearrange(
79+
da,
80+
[{"e": ["c", "d"]}, {"f": ["a", "b"]}]
81+
)
82+
# string syntax
83+
rearrange(da, "(c d)=e (a b)=f")
84+
# dims in output: `e`, `f`
85+
86+
# ----------------------------
87+
88+
# list syntax
89+
rearrange(
90+
da,
91+
["a2", "c", "a1", {"e": ["d", "b"]}],
92+
pattern_in=[{"a": ["a1", "a2"]}]
93+
)
94+
# string syntax
95+
rearrange(da, "(a1 a2)=a -> a1 c a2 (d b)=e")
96+
# dims in output: `a1`, `c`, `a2`, `e`
97+
```

docs/source/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
## v0.x.x (Unreleased)
44
### New features
55
* {func}`.ecdf` now returns a DataArray to be compatible with {meth}`~xarray.Dataset.map` {pull}`47`
6+
* Added `.linalg` and `.einops` accessors for `DataArray` objects {pull}`51`
67

78
### Maintenance and fixes
89
* Update dependencies and follow new pylint recommendations {pull}`49`
910

1011
### Documentation
12+
* Add documentation showing how to use accessors {pull}`51`
13+
* Ease running einops tutorial locally {pull}`51`
1114

1215
## v0.5.1 (2023 Jan 20)
1316
### Maintenance and fixes

docs/source/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"jupyter_sphinx",
4242
"sphinx_design",
4343
"matplotlib.sphinxext.plot_directive",
44+
"sphinx_togglebutton",
4445
]
4546

4647
templates_path = ["_templates"]

docs/source/contributing/dev_reference.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ Runs test suite with pytest
5858
:toctree: generated/
5959
6060
PairHandler
61+
_translate_pattern_string
6162
_einsum_parent
63+
_einsum_path
64+
_einsum
6265
```
6366

6467
### Einops
@@ -70,6 +73,8 @@ Runs test suite with pytest
7073
DimHandler
7174
process_pattern_list
7275
translate_pattern
76+
_reduce
77+
_rearrange
7378
```
7479

7580
### Tutorial

0 commit comments

Comments
 (0)