pymor.vectorarrays

Extended functionality for pyMOR vector arrays

source

Lbl

def Lbl(
    *args, **kwds
):

Enum where members are also (and must be) strings


source

unlabel_dims

def unlabel_dims(
    obj
):
from sparse import COO, GCXS, SparseArray

XarrayVectorSpace


source

dataarray_coordinate_data

def dataarray_coordinate_data(
    da:xarray.core.dataarray.DataArray, dim:str
)->tuple:

source

default_coordinate

def default_coordinate(
    dim:str='len', size:int | list[int] | tuple[int] | None=None
)->tuple:
da = DataArray(np.ones([1,2,3]), dims=['A', 'B', 'C'], coords={'A': ('A', [0]), 'C': ('C', [0, 1, 2])})
[dataarray_coordinate_data(da, dim) for dim in ['A', 'B', 'C']]
[(array([0]), {}), (array([0, 1]),), (array([0, 1, 2]), {})]
_
[(array([0]), {}), (array([0, 1]),), (array([0, 1, 2]), {})]

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

____

def ____(
    obj:None, shape:NoneType=None
):

source

validate_coord_data

def validate_coord_data(
    obj, shape:NoneType=None
)->dict:
validate_coord_data(da)
{'A': (array([0]), {}), 'B': (array([0, 1]),), 'C': (array([0, 1, 2]), {})}
validate_coord_data(da.coords)
{'A': (array([0]), {}), 'C': (array([0, 1, 2]), {})}
validate_coord_data({'A': (array([0]), {}), 'C': array([0, 1, 2])})
{'A': (array([0]), {}), 'C': (array([0, 1, 2]),)}
validate_coord_data('A')
{'A': (['A'],)}
validate_coord_data('A', 3)
{'A': (array([0, 1, 2]),)}
validate_coord_data(['A', 'B'], [3, 0])
{'A': (array([0, 1, 2]),), 'B': (['B'],)}
validate_coord_data(3)
{3: (array([0, 1, 2]),)}
validate_coord_data(None)
{}

source

coord_data_shape

def coord_data_shape(
    coord_data
):

source

make_coordinates

def make_coordinates(
    coord_data:dict
)->xarray.core.coordinates.Coordinates:

source

XarrayVectorSpace

def XarrayVectorSpace(
    coord_data:xarray.core.coordinates.Coordinates | dict | xarray.core.dataarray.DataArray | str | None=None,
    name:str | None=None, attrs:dict | None=None,
    id:NoneType=None, # See `~pymor.vectorarrays.interface.VectorSpace.id`.
):

VectorSpace of XarrayVectorArrays.

“Empty” XarrayVectorSpace with no coordinates (used, for example, for operators whose range is a scalar):

space1 = XarrayVectorSpace()
space1
<xarray.DataArray 'XarrayVectorSpace' ()> Size: 8B
array(0.)

XarrayVectorSpace from dictionary of coordinates:

coords = {'A': [1, 2, 3]}
space1 = XarrayVectorSpace(coords)
space1
A(3)
<xarray.DataArray 'XarrayVectorSpace' (A: 3)> Size: 24B
array([0., 0., 0.])
Coordinates:
  * A        (A) int64 24B 1 2 3

The DataArray is created lazily:

vars(space1)
{'coord_data': {'A': ([1, 2, 3],)},
 '_name': None,
 'attrs': None,
 'id': None,
 'dims': ['A'],
 'ndim': 1,
 'shape': [3],
 'size': 3,
 '_locked': True,
 '_array': <xarray.DataArray 'XarrayVectorSpace' (A: 3)> Size: 24B
 array([0., 0., 0.])
 Coordinates:
   * A        (A) int64 24B 1 2 3}
space1.coords
Coordinates:
  * A        (A) int64 24B 1 2 3
vars(space1)
{'coord_data': {'A': ([1, 2, 3],)},
 '_name': None,
 'attrs': None,
 'id': None,
 'dims': ['A'],
 'ndim': 1,
 'shape': [3],
 'size': 3,
 '_locked': True,
 '_array': <xarray.DataArray 'XarrayVectorSpace' (A: 3)> Size: 24B
 array([0., 0., 0.])
 Coordinates:
   * A        (A) int64 24B 1 2 3,
 'coords': Coordinates:
   * A        (A) int64 24B 1 2 3}
coords = {'A': [1, 2, 3], 'B': ['a', 'b']}
space2 = XarrayVectorSpace(coords)
space2
A(3) ⛒ B(2)
<xarray.DataArray 'XarrayVectorSpace' (A: 3, B: 2)> Size: 48B
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
Coordinates:
  * A        (A) int64 24B 1 2 3
  * B        (B) <U1 8B 'a' 'b'

From a list of coordinates with attributes:

coords = {'A': ([1, 2, 3], {'short_name': 'a'}), 'B': (['a', 'b'], {'short_name': 'b'})}
XarrayVectorSpace(coords)
A(3) ⛒ B(2)
<xarray.DataArray 'XarrayVectorSpace' (A: 3, B: 2)> Size: 48B
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
Coordinates:
  * A        (A) int64 24B 1 2 3
  * B        (B) <U1 8B 'a' 'b'

From xarray Coordinates:

coords
{'A': ([1, 2, 3], {'short_name': 'a'}), 'B': (['a', 'b'], {'short_name': 'b'})}
coords = make_coordinates(coords)
XarrayVectorSpace(coords)
A(3) ⛒ B(2)
<xarray.DataArray 'XarrayVectorSpace' (A: 3, B: 2)> Size: 48B
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
Coordinates:
  * A        (A) int64 24B 1 2 3
  * B        (B) <U1 8B 'a' 'b'

From DataArray:

da = DataArray(np.ones(coords.shape), coords=coords, name='C')
space = XarrayVectorSpace(da)
space
A(3) ⛒ B(2)
<xarray.DataArray 'C' (A: 3, B: 2)> Size: 48B
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
Coordinates:
  * A        (A) int64 24B 1 2 3
  * B        (B) <U1 8B 'a' 'b'
space.dim
6
space.ndim
2

source

XarrayVectorSpace.rename

def rename(
    name
):
space = XarrayVectorSpace({'A': [1, 2], 'B': ['a', 'b', 'c']}, name='boo')
space
A(2) ⛒ B(3)
<xarray.DataArray 'boo' (A: 2, B: 3)> Size: 48B
array([[0., 0., 0.],
       [0., 0., 0.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.name
'boo'
space.rename('foo').name
'foo'

source

XarrayVectorSpace.__eq__

def __eq__(
    other
):

Return self==value.

space == space
True
space == space.rename('foo')
True

source

XarrayVectorSpace.__mul__

def __mul__(
    other
):
space2 = XarrayVectorSpace({'C': [1, 2], 'D': ['a', 'b', 'c']}, name='foo')
space3 = space * space2
space3
A(2) ⛒ B(3) ⛒ C(2) ⛒ D(3)
<xarray.DataArray 'foo' (A: 2, B: 3, C: 2, D: 3)> Size: 288B
array([[[[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]]],


       [[[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]]]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
  * C        (C) int64 16B 1 2
  * D        (D) <U1 12B 'a' 'b' 'c'
space3 == XarrayVectorSpace(space.coords + space2.coords)
True
space3.name
'foo'
space2 * space2 == space2
True

XarrayVectorArray


source

transpose_like

def transpose_like(
    a:numpy.ndarray, dims, new_dims
):
impl = XarrayVectorArrayImpl(
    np.arange(6).reshape(2, 3, 1), 
    space, 
    ['A', 'B', 'C'], 
    {"C": [0]}
)
impl
XarrayVectorArrayImpl(
    array([[[0, 1, 2], [3, 4, 5]]]),
    XarrayVectorSpace(coord_data={A: ([1, 2],), B: (['a', 'b', 'c'],)}, name='boo'),
    _data_dims=['C', 'A', 'B'],
    _extended_coord_data={C: ([0],)})
len(impl)
1
impl.array
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
# #|export
# #|hide
# def _abbreviate(s):
#     s = s.split('(')[0]
#     words = s.split()
#     if len(words) > 1: return ''.join(w[0].capitalize() for w in words)
#     return s[:2]
# #|export
# #|hide
# def _coords_str(coords, dims=None):
#     if not coords: return '{1}'
#     if dims is None: dims = list(coords)
#     return '{' + ' ⨉ '.join(f'{dim}({len(coords[dim])})' for dim in dims) + '}'
# #|export
# def _short_coords_str(coords, dims=None):
#     if not coords: return '{1}'
#     if dims is None: dims = list(coords)
#     return '{' + ' ⨉ '.join(f'{_abbreviate(dim)}({len(coords[dim])})' for dim in dims) + '}'
U = XarrayVectorArray(space, impl)
U
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.data
array([[[0, 1, 2],
        [3, 4, 5]]])
U.array
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.shape
(1, 2, 3)
U.coords
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.dims
['A', 'B']
U.extended_dims
['C']
U.extended_coord_data
{'C': ([0],)}

source

XarrayVectorSpace.from_data

def from_data(
    data, data_dims:NoneType=None, extended_coord_data:NoneType=None
):

Create a VectorArray with an extended dimension:

U = space.from_data(
    np.arange(6).reshape(2, 3, 1), 
    ['A', 'B', 'C'], 
    {"C": [0]}
)
U
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.data
array([[[0, 1, 2],
        [3, 4, 5]]])
U.array
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.shape
(1, 2, 3)
U.coords
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.dims
['A', 'B']
U.extended_dims
['C']
U.extended_coord_data
{'C': ([0],)}

Create a VectorArray with no extended dimension:

U = space.from_data(
    np.arange(6).reshape(2, 3),
    ['A', 'B'],
)
U
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0, 1, 2],
       [3, 4, 5]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.data
array([[0, 1, 2],
       [3, 4, 5]])
U.array
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0, 1, 2],
       [3, 4, 5]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.shape
(2, 3)
U.coords
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.dims
['A', 'B']
U.extended_dims
[]
U.extended_coord_data
{}

source

XarrayVectorSpace.from_numpy

def from_numpy(
    data:numpy.ndarray, extended_coord_data:dict | str | None=None, id:NoneType=None, ensure_copy:bool=False
)->__main__.XarrayVectorArray: # A vector array with data from the numpy array

Return an XarrayVectorArray in the vector space with data from the ndarray data.

space.from_numpy(np.arange(6))
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0, 1, 2],
       [3, 4, 5]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.from_numpy(np.arange(6), {"C": [0]})
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorSpace.from_xarray

def from_xarray(
    data:xarray.core.dataarray.DataArray
)->__main__.XarrayVectorArray:

Return an XarrayVectorArray containing data from DataArray data.

da = space.from_numpy(np.arange(6)).array
da
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0, 1, 2],
       [3, 4, 5]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.from_xarray(da)
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0, 1, 2],
       [3, 4, 5]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

An XarrayVectorArray from an array in space plus extended dimensions:

da = da * DataArray([1], coords={'C': [0]})
da
<xarray.DataArray (A: 2, B: 3, C: 1)> Size: 48B
array([[[0],
        [1],
        [2]],

       [[3],
        [4],
        [5]]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
  * C        (C) int64 8B 0
space.from_xarray(da)
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0, 1, 2],
        [3, 4, 5]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorSpace.concatenate

def concatenate(
    arrays, dim
):

source

XarrayVectorSpace.array_from_fn

def array_from_fn(
    fn, extended_coords:dict | str | None=None, # Coordinates to extend vector space over
    reserve:int=0
)->__main__.XarrayVectorArray: # `XarrayVectorArray` with all elements equal to zero

Return XarrayVectorArray of null vectors in XarrayVectorSpace optionally extended to include supplied coordinates coords.


source

XarrayVectorSpace.zeros

def zeros(
    extended_coords:dict | None=None, # Coordinates to extend vector space over
    reserve:int=0
)->__main__.XarrayVectorArray: # `XarrayVectorArray` with all elements equal to zero

Return XarrayVectorArray of null vectors in XarrayVectorSpace optionally extended to include supplied coordinates coords.

space.zeros()
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0., 0., 0.],
       [0., 0., 0.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.zeros({'C': [0]})
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0., 0., 0.],
        [0., 0., 0.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorSpace.ones

def ones(
    extended_coords:dict | None=None, # Coordinates to extend vector space over
    reserve:int=0
)->__main__.XarrayVectorArray: # `XarrayVectorArray` with all elements equal to one

Return XarrayVectorArray of vectors with each element equal to one in XarrayVectorSpace optionally extended to include supplied coordinates coords.

space.ones()
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[1., 1., 1.],
       [1., 1., 1.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.ones({'C': [0]})
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[1., 1., 1.],
        [1., 1., 1.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorSpace.random

def random(
    extended_coords:NoneType=None,
    distribution:str='uniform', # Random distribution to use (`'uniform'`, `'normal'`).
    name:NoneType=None
)->__main__.XarrayVectorArray: # A random `XarrayVectorArray` in the vector space

Create a |VectorArray| of vectors with random entries.

Supported random distributions::

'uniform': Uniform distribution in half-open interval
           [`low`, `high`).
'normal':  Normal (Gaussian) distribution with mean
           `loc` and standard deviation `scale`.

Note that not all random distributions are necessarily implemented by all |VectorSpace| implementations.

Parameters

count The number of vectors. distribution Random distribution to use ('uniform', 'normal'). low Lower bound for 'uniform' distribution (defaults to 0). high Upper bound for 'uniform' distribution (defaults to 1). loc Mean for 'normal' distribution (defaults to 0). scale Standard deviation for 'normal' distribution (defaults to 1). reserve Hint for the backend to which length the array will grow.

from pymor.tools.random import new_rng
with new_rng(42):
    U = space.random()
U
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[0.77395605, 0.85859792, 0.09417735],
       [0.43887844, 0.69736803, 0.97562235]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
with new_rng(42):
    U = space.random({'C': [0]})
U
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0.77395605, 0.85859792, 0.09417735],
        [0.43887844, 0.69736803, 0.97562235]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorSpace.__contains__

def __contains__(
    other
):
space in space2
False
space in space
True
U = space.zeros({'C': range(2)})
U
C(2) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 2, A: 2, B: 3)> Size: 96B
array([[[0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U in space
True

source

XarrayVectorArray.array_labeled_as_source

def array_labeled_as_source():
U.array_labeled_as_source()
<xarray.DataArray (C: 2, A (source): 2, B (source): 3)> Size: 96B
array([[[0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.]]])
Coordinates:
  * C           (C) int64 16B 0 1
  * A (source)  (A (source)) int64 16B 1 2
  * B (source)  (B (source)) <U1 12B 'a' 'b' 'c'

source

XarrayVectorArray.item

def item():

Return the single value stored in the array if there is only one value.

XarrayVectorSpace({'i': [0]}).ones().item()
1.0
# #|export
# @patch(as_prop=True)
# def dims(self:XarrayVectorArray): return self.array.dims
# #|export
# @patch
# def stacked_data(self:XarrayVectorArray):
#     return transpose_like(
#         self.data, self.array.dims, self.dims + self.extended_dims
#     ).reshape(
#         self.space.size, *(self.extended_shape or [1])
#     )

source

XarrayVectorArrayImpl.stacked_data

def stacked_data():
U
C(2) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 2, A: 2, B: 3)> Size: 96B
array([[[0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U = space.zeros({'C': np.arange(2), 'D': np.arange(2)})
U.impl.stacked_data().shape
(6, 4)
U = space.zeros()
U.impl.stacked_data()
array([[0.],
       [0.],
       [0.],
       [0.],
       [0.],
       [0.]])
U = space.zeros({'C': range(2)})
U.impl.stacked_data()
array([[0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.]])

VectorArray.to_numpy

def to_numpy(
    ensure_copy:bool=False, # If `False`, modifying the returned |NumPy array| might alter the original
    # |VectorArray|. If `True` always a copy of the array data is made.
):

Return (self.dim, len(self)) NumPy Array with the data stored in the array.

Parameters

ensure_copy If False, modifying the returned |NumPy array| might alter the original |VectorArray|. If True always a copy of the array data is made.

U.to_numpy().shape
(6, 2)

This gives the same result as for a dimension-6 NumpyVectorSpace:

NumpyVectorSpace(6).zeros(2).to_numpy().shape
(6, 2)
space.zeros(space2.coords).shape
(2, 3, 2, 3)
space.zeros(space2.coords).to_numpy().shape
(6, 6)
# #|export
# @patch
# def rename(
#     self:XarrayVectorArray,
#     new_name_or_name_dict=None,
#     **names,
# ):
#     """Rename the vector array and/or any of its dimensions."""
#     vec = self.space.rename(new_name_or_name_dict, **names).from_xarray(self.array.rename(new_name_or_name_dict, **names))
#     if isinstance(new_name_or_name_dict, str): vec.name = new_name_or_name_dict
#     return vec
# U.rename('baz', A='bar')
space
A(2) ⛒ B(3)
<xarray.DataArray 'boo' (A: 2, B: 3)> Size: 48B
array([[0., 0., 0.],
       [0., 0., 0.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U = space.ones({'C': [0]})
U
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[1., 1., 1.],
        [1., 1., 1.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U.scal(2)
U.data
array([[[2., 2., 2.],
        [2., 2., 2.]]])
U * 1j
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 96B
array([[[0.+2.j, 0.+2.j, 0.+2.j],
        [0.+2.j, 0.+2.j, 0.+2.j]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 = space.ones({'C': [0]})
U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[1., 1., 1.],
        [1., 1., 1.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U2 = space.ones()
U2
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[1., 1., 1.],
       [1., 1., 1.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1.axpy(2, U2)
U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[3., 3., 3.],
        [3., 3., 3.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 = space.ones({'C': [0]})
U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[1., 1., 1.],
        [1., 1., 1.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1.axpy(2, U1)
U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[3., 3., 3.],
        [3., 3., 3.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 = space.ones({'C': [0]})
U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[1., 1., 1.],
        [1., 1., 1.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 + U1
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[2., 2., 2.],
        [2., 2., 2.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U2 = space.ones()
U1 + U2
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[2., 2., 2.],
        [2., 2., 2.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'

source

XarrayVectorArray.__mul__

def __mul__(
    other
):
U1 = space.ones({'C': [0]})
da = DataArray(np.arange(3), {'B': U1.array.B})
da
<xarray.DataArray (B: 3)> Size: 24B
array([0, 1, 2])
Coordinates:
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 * da
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0., 1., 2.],
        [0., 1., 2.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space.ones() * space2.zeros()
∅ ⛒ A(2) ⛒ B(3) ⛒ C(2) ⛒ D(3)
<xarray.DataArray (A: 2, B: 3, C: 2, D: 3)> Size: 288B
array([[[[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]]],


       [[[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [0., 0., 0.]]]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
  * C        (C) int64 16B 1 2
  * D        (D) <U1 12B 'a' 'b' 'c'
U1 = space.ones()
U1
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 48B
array([[1., 1., 1.],
       [1., 1., 1.]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U2 = XarrayVectorSpace(U1.array.B).from_numpy(np.arange(3), extended_coord_data={'C': [0]})
U2
C(1) ⛒ B(3)
<xarray.DataArray (C: 1, B: 3)> Size: 24B
array([[0, 1, 2]])
Coordinates:
  * C        (C) int64 8B 0
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 * U2
C(1) ⛒ A(2) ⛒ B(3)
<xarray.DataArray (C: 1, A: 2, B: 3)> Size: 48B
array([[[0., 1., 2.],
        [0., 1., 2.]]])
Coordinates:
  * C        (C) int64 8B 0
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
U1 * 1j
∅ ⛒ A(2) ⛒ B(3)
<xarray.DataArray (A: 2, B: 3)> Size: 96B
array([[0.+1.j, 0.+1.j, 0.+1.j],
       [0.+1.j, 0.+1.j, 0.+1.j]])
Coordinates:
  * A        (A) int64 16B 1 2
  * B        (B) <U1 12B 'a' 'b' 'c'
space = XarrayVectorSpace({'A': [1], 'B': ['a', 'b']}, name='boo')
space
A(1) ⛒ B(2)
<xarray.DataArray 'boo' (A: 1, B: 2)> Size: 16B
array([[0., 0.]])
Coordinates:
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
U = space.ones({'C': range(2)}) + 1j * space.ones({'C': range(2)})
U.real
C(2) ⛒ A(1) ⛒ B(2)
<xarray.DataArray (C: 2, A: 1, B: 2)> Size: 32B
array([[[1., 1.]],

       [[1., 1.]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
U.imag
C(2) ⛒ A(1) ⛒ B(2)
<xarray.DataArray (C: 2, A: 1, B: 2)> Size: 32B
array([[[1., 1.]],

       [[1., 1.]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
U
C(2) ⛒ A(1) ⛒ B(2)
<xarray.DataArray (C: 2, A: 1, B: 2)> Size: 64B
array([[[1.+1.j, 1.+1.j]],

       [[1.+1.j, 1.+1.j]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
U.conj()
C(2) ⛒ A(1) ⛒ B(2)
<xarray.DataArray (C: 2, A: 1, B: 2)> Size: 64B
array([[[1.-1.j, 1.-1.j]],

       [[1.-1.j, 1.-1.j]]])
Coordinates:
  * C        (C) int64 16B 0 1
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
U.reim
Part(2) ⛒ C(2) ⛒ A(1) ⛒ B(2)
<xarray.DataArray (Part: 2, C: 2, A: 1, B: 2)> Size: 64B
array([[[[1., 1.]],

        [[1., 1.]]],


       [[[1., 1.]],

        [[1., 1.]]]])
Coordinates:
  * Part     (Part) <U2 16B 'Re' 'Im'
  * C        (C) int64 16B 0 1
  * A        (A) int64 8B 1
  * B        (B) <U1 8B 'a' 'b'
# #|export
# def _plotly_automargin(plot, element):
#     plot.state['layout']['yaxis']['automargin'] = True
#     plot.state['layout']['xaxis']['automargin'] = True
# #|export
# def _delete(string, strings):
#     for s in strings: string = string.replace(s, '')
#     return string
# #|export
# def _set_scrubber_fractional_value(column, fraction): 
#     scrubber = column.objects[1].objects[0]
#     scrubber.value = round(scrubber.end * fraction)
# #|export
# def _scaled_loc(arr, fraction):
#     return arr[int(len(arr) * fraction)]
# #|export
# def capitalize_first(s:str|list[str]) -> str|list[str]:
#     """Capitalize the first letter of a string or each string in a list."""
#     if not s: return s
#     if isinstance(s, list):
#         return [capitalize_first(item) for item in s]
#     return s[0].upper() + s[1:]
# #|export
# def _long_name(da):
#     if not isinstance(da, DataArray): return da
#     return da.attrs.get('long_name', da.name) or ''

# def get_long_name(*args, capitalize:bool=True):
#     out = ' '.join(_long_name(arg) for arg in args)
#     if not out: return ''
#     if capitalize: return capitalize_first(out)
#     return out

source

get_axis_label

def get_axis_label(
    da:xarray.core.dataarray.DataArray
):

source

XarrayVectorArray.visualize

def visualize(
    *, slider_label_precision:int=2
):

Visualize the data contained in the XarrayVectorArray. Put the first dimension with numerical coordinates on the x axis, and include a scrubber if there is a second numerical dimension. Atomic velocity is prioritized to be on the x axis, time is prioritized to be on the scrubber. Put categorical dimensions in the legend. If the data are complex, add the real and imaginary parts as a categorical dimension. If there are no numerical dimensions, plot the categorical dimension(s) as a horizontal bar plot.

space = XarrayVectorSpace({'foo': ['aaaaaaaaaaaaaaaaaa', 'b', 'c']})
U1 = space.random(name='bar')
U2 = 1j * space.random(name='bar')
U3 = space.random({'baz': np.arange(5)}, name='bar')
U4 = 1j * space.random({'baz': np.arange(5)}, name='bar')
U5 = space.random({'baz': np.arange(5), 'bing': .000123456 * np.linspace(0, 5, 6)}, name='bar')
U1.visualize()
(U1 + U2).visualize()
U3.visualize(line_width=10)
U3.visualize(title='biz', markers=True, xaxis_range=(.5, 3), line_width=0)
(U3 + U4).visualize()
U5.visualize(slider_label_precision=5)