Skip to content

fiery.xtensor

Named dimensions and coordinate labels for PyTorch tensors.

fiery.xtensor makes names a first-class citizen of torch.Tensor, in the spirit of xarray:

  • XTensor (also available lowercase as xtensor) is an xarray-like DataArray over a live torch.Tensor: it carries self-managed named dimensions and, optionally, per-dimension coordinate labels (coords, keyed by dimension name) through a wide range of operations. Select by label with .sel, by position with .isel, or reach a single label by attribute (x.red).
  • xvector and xmatrix are convenience factories that name and label a "channel" axis (or "row"/"col") and return a plain XTensor.

The x* factories (xzeros, xones, xfill, ...) build an XTensor directly from the matching torch.* factory, naming (and labelling) the axes at creation time; the x*_like variants inherit an XTensor input's names, coordinates, and unit.

as_xtensor is the XTensor analogue of torch.as_tensor: coerce a bare number, a plain Tensor, or an XTensor into an XTensor, graph-safely, preserving unit/names/coords unless a keyword explicitly overrides them. Like torch.as_tensor, it also accepts dtype=/device= to convert the underlying data.

is_xtensor is the XTensor analogue of torch.is_tensor.

Classes

ExtendedTensor

Bases: Tensor

A torch.Tensor subclass with extended, name-aware behaviour.

Selected torch functions are overridden through the __torch_function__ protocol; the overrides live in a per-subclass registry, populated by the overrides decorator. Any op without an override still propagates the subclass's own metadata attributes from its first tensor argument onto the result.

Methods:

overrides classmethod
overrides(func: Optional[Callable]) -> Callable

Decorator to register a function override.

func may be None (an op that does not exist in the running PyTorch version); in that case the override is silently skipped so that we never overload a function that is missing from this PyTorch build.

set_options

set_options(**options: Any)

Set one or more options, globally or for a with block.

Options:

  • combine_axes -- how axis descriptors (type/orientation/any custom field) combine when two operands meet in a name-aware op (broadcast, alignment, cat/stack/matmul/einsum/…). Either a single policy applied to every field, or a {field: policy} dict for per-field control (with "*" as the default for unlisted fields). Policies:

    • "drop_conflicts" (default) -- keep a field the operands agree on, drop it where they conflict;
    • "strict" (alias "raise") -- raise ValueError on a conflict;
    • "override" -- keep the left operand's value;
    • "drop" -- always drop the field.
  • unit_backend -- the physical-unit engine for data units: None (default) means units are inert opaque strings; "pint" enables validation/algebra/conversion (and is rejected at set time if pint is not installed).

  • unit_policy -- what a dimensionally invalid/ambiguous step does: "drop" (default) silently drops the unit, "strict" raises.
  • interp_bound -- the default boundary condition for interp, i.e. how an out-of-range query is resolved. "replicate" (default) clamps to the edge value; other names ("wrap", "reflect", "mirror", "zero", …) mirror fiery.interpol. A per-call bound= overrides it.
  • interp_extrapolate -- whether interp extrapolates past the ends (True (default); with interp_bound="replicate" this is the clamp). A per-call extrapolate= overrides it.

Any option can be set permanently or only for a with block:

set_options(combine_axes="strict")                    # until changed
with set_options(combine_axes="strict"):              # for this block
    ...
# per-field: drop everything, but a clashing `type` is an error
with set_options(combine_axes={"*": "drop", "type": "raise"}):
    ...

XTensor

XTensor(*args, **kwargs)

Bases: ExtendedTensor

A tensor with named dimensions and, optionally, per-dimension coordinate labels -- an xarray-like DataArray over a live torch.Tensor.

  • Dimensions are named through names (self-managed in _axis_names, independent of PyTorch's experimental builtin named-tensor feature, so the class works even where that API has been removed).
  • Coordinates label the positions along a named dimension. They live in coords -- a mapping dim name -> labels -- keyed by dimension name, so they follow their dimension through reshaping/reordering with no positional bookkeeping. A labelled dimension must be named.
  • Axis descriptors may enrich a name with extra fields -- any custom key you like (type is the OME-NGFF convention shown in examples; orientation is the one field with built-in behaviour) -- passed as a dict in place of a bare name ({"name": "x", "type": "space"}). names stays the ergonomic view (bare names); axes returns the full descriptors. The extra fields live in _axis_meta, keyed by dimension name, so they follow the dimension like coordinates do.

Select by label with sel, by integer position with isel, or reach a single label by attribute (x.red).

Attributes

names property writable
names: tuple[str | None, ...]

The name of each axis (None for unnamed axes). On assignment a single ... expands to a run of unnamed axes, so x.names = ("b", ..., "w") names only the ends and leaves the middle unnamed.

coords property writable
coords: dict[str, LabelsT]

The coordinates, as a {dim name: coordinate} dict. A coordinate is a tuple of labels, or a compact numeric coordinate ({spacing[, origin]}, whose ["values"] key materialises the positions).

Only entries that are still valid are returned -- every dim a coordinate spans must still be named on this tensor (and, for labels, its size must match the label count) -- so stale metadata propagated onto a shape-changing op is hidden.

A dimension coordinate spans just the dim it is keyed under (it is that dim's index, so .sel(name=...) works); a non-dimension coordinate (its key is not itself a dim name) rides along some other dim(s) instead, and is not an index. A non-dimension coordinate may span several dims at once: a compact affine map (spacing is a vector, one component per spanned dim, origin a single scalar shared across them), or an explicit grid of values with no regular spacing (e.g. lat(y, x)), one tensor axis per spanned dim.

unit property writable
unit: Optional[str]

The physical unit of the tensor's values (the data unit, Proposal 0003), or None. Assigning annotates (it never changes the data); to_unit converts. Under unit_backend="pint" the unit is validated and normalised on set; with the default unit_backend=None it is an opaque string that is simply carried through operations.

axes property writable
axes: tuple[dict | None, ...]

Each axis as a descriptor dict {"name": ..., **extra} (or None for an unnamed axis). The extra fields -- any custom key (type by OME-NGFF convention, orientation, ...) -- come from _axis_meta, keyed by dimension name.

magnitude property
magnitude: Self

The tensor with its data unit dropped -- the bare values, still an XTensor with the same names and coordinates. A view (no data copy); the original is unchanged. x.magnitude.unit is always None. (To get a plain torch.Tensor, use x.as_subclass(torch.Tensor).)

mT property
mT: Self

Transpose of the last two dimensions (names included).

Methods:

to_unit
to_unit(unit: str) -> Self

Convert the data to unit, rescaling the values by the conversion factor (requires a unit already set and unit_backend="pint").

rename
rename(*names: str | None, **rename_map: str) -> Self

Return a view with renamed axes (self-managed; not the builtin op).

Call positionally (x.rename("a", "b")), with None to clear all names (x.rename(None)), or with a mapping to rename specific axes (x.rename(old="new")). A single ... keeps the axes it spans unchanged (x.rename("A", ..., "Z")). Coordinates follow their (renamed) dimension.

rename_
rename_(*names: str | None, **rename_map: str) -> Self

In-place variant of rename.

swap_dims
swap_dims(dims_map: Optional[dict] = None, **kwargs: str) -> Self

Promote a non-dimension coordinate to be its dim's index, demoting the previous index to ride along under its old key -- xarray's swap_dims. {old_dim: new_name} (positionally or as keywords): new_name must already be a non-dimension coordinate riding old_dim alone (coords={..., new_name: (old_dim, values)}).

da.swap_dims({"time": "label"}).sel(label="c")   # promote, then select

The axis itself is renamed old_dim -> new_name (so .names and any axis descriptor follow, like rename); every other coordinate riding old_dim keeps its own key and simply rides the renamed axis.

swap_dims_
swap_dims_(dims_map: Optional[dict] = None, **kwargs: str) -> Self

In-place variant of swap_dims.

isel
isel(**indexers: Any) -> Self

Select by integer position along named dimensions.

x.isel(row=0, col=slice(1, 3)) indexes row at position 0 and col at positions 1..2, leaving the other axes untouched.

sel
sel(*indexers_positional: Mapping, mode: Optional[str] = None, tolerance: Any = None, method: Optional[str] = None, **indexers_kwargs: Any) -> Self

Select by coordinate label (or numeric value) along named dims.

x.sel(channel="red") selects the position whose label is "red". A list of labels selects several positions; a single label drops the dimension (like integer indexing). For structured coordinates, a str matches a label's "name", and a dict queries the labels' fields (x.sel(channel={"type": "signal"})), keeping the axis and selecting every match.

On a numeric coordinate, the selector is a value (x.sel(t="2s")). mode chooses which tick an inexact value snaps to:

  • "round" (default) — the nearest tick by value;
  • "floor" / "ceil" — the largest tick <= / smallest tick >= the value (value space, robust to a descending coordinate);
  • "prev" / "next" — the neighbouring tick at the lower / higher index (tick order; needs a monotonic coordinate).

tolerance (a value in the position unit) caps the allowed gap. A bare .sel(t=v) is exact (tolerance=0); passing a mode implies an unbounded snap unless a tolerance is given.

A slice(lo, hi) on a numeric coordinate is a value range, unit-aware, resolving to a contiguous integer slice — half-open like ordinary Python indexing (lo <= value < hi), not xarray's inclusive-both-ends convention (see the "Differences from xarray" guide). Bounds are compared numerically regardless of order or of the coordinate's own direction: t=slice(1, 5) and t=slice(5, 1) select the same range. A one-sided range keeps the bound in the slot it was given (slice(1, None) -> value >= 1; slice(None, 5) -> value < 5); an out-of-range or empty result is a well-formed empty axis, not an error. slice.step is not supported (mode/tolerance don't apply to a range either).

A joint query over several dims sharing one coordinate (e.g. a lat/lon pair that together locate a point on a 2-D grid) picks all of those dims' positions in one shot: pass a value for every coordinate name that spans the same dims (x.sel(lat=52.1, lon=4.3)) — no dedicated syntax, ordinary keyword arguments that happen to share dims are recognised as one joint system. Only a square query is supported (exactly one coordinate value per spanned dim); an under- or over-determined query raises rather than guessing. Only mode="round" (the default) applies to a joint query — floor/ceil/prev/next have no well-defined meaning across several coupled dims at once. tolerance still applies, per queried coordinate name (a bare query is exact by default), checked against the chosen position's own value.

On an irregular grid coordinate (an explicit multi-dim array with no regular spacing, e.g. an irregular satellite-swath lat/lon), a joint query works the same way — one value per coordinate name spanning the same dims — but resolves to the single nearest grid point across the queried coordinates' raw magnitudes. Mixing coordinates with very different units (degrees and metres, say) weighs the nearer one more heavily, same as any unnormalised distance always does. Only a single point is supported per call, not a vectorized query over many points at once. tolerance/mode/method behave the same as the joint case above (only the default "nearest" mode applies; a gap over tolerance raises).

Pass indexers as an explicit mapping (x.sel({"mode": "red"})) instead of keyword arguments when a dim's name collides with one of sel's own keyword parameters (mode, tolerance, method) — xarray's own escape hatch for exactly this, since a keyword argument matching one of those names is always bound to the parameter, never reaching the indexers. Passing both raises.

interp
interp(*indexers_positional: Mapping, method: Any = 'linear', bound: Any = None, extrapolate: Any = None, name: Optional[str] = None, **indexers_kwargs: Any) -> Self

Interpolate onto new coordinate values along named dims.

Where sel picks existing positions, interp computes values at arbitrary positions of a numeric coordinate, the xarray way:

x.interp(t=2.5)                   # one point -> drops the axis
x.interp(t=[0.0, 0.5, 1.0])       # several  -> keeps the axis
x.interp(t="2.5s")                # unitful (backend converts)
x.interp(t=q, method="cubic")     # a query tensor (grads flow)

method is the interpolation order -- "nearest" (built in) or a higher order ("linear" (default), "quadratic", "cubic", or an int), which needs the optional fiery.interpol backend (pip install fiery-xtensor[interp]). An out-of-range query follows bound (default: the interp_bound option -- "replicate" clamps to the edge) and extrapolate (default: the interp_extrapolate option); both can be set with set_options.

A scalar query drops the axis (like sel); a list/tensor keeps it, its coordinate becoming the queried positions. A regular (evenly-spaced) coordinate supports every method; an irregular (explicit values) one only supports "nearest"/"linear", both exact, since the map between value space and index space is locally linear between two bracketing ticks. A higher order needs a true non-uniform spline in value space, which isn't currently supported for an irregular coordinate.

A joint query over several dims that share one coordinate (e.g. a lat/lon pair spanning several dims at once) resolves to a fractional position -- never rounded -- across all of them at once, then interpolates in that many dimensions together (falling back to a built-in nearest gather for method="nearest", no extra backend needed). A query with every name given as a scalar is a single point: all the spanned dims drop, like the 1-D scalar case above. Any name given as a list/tensor makes it "many": every name's query broadcasts to a common length N, and the spanned dims collapse into one new axis of N sampled points -- not an outer-product grid, since the dims are coupled and you can't vary one queried name without moving through every spanned dim at once (mirroring xarray's own vectorized/pointwise-indexing convention for a value-based query on a multi-dim coordinate). The new axis is named name if given, else the shared name of any query that is itself a named 1-D XTensor -- x.interp(lat=XTensor([...], names=("pts",)), lon=[...]) needs no name= at all, mirroring how xarray derives the result's new dimension from the indexer arrays' own shared dim name -- else unnamed (matching xstack's convention for a brand-new axis with nothing to infer from). When a name is resolved, the axis carries every queried name's own sampled values as a riding coordinate -- an unnamed axis can't be keyed, so it has none. Only one such joint group is supported per call; call interp again for a second group.

Pass indexers as an explicit mapping (x.interp({"method": 5.0})) instead of keyword arguments when a dim's name collides with one of interp's own keyword parameters (method, bound, extrapolate, name) -- xarray's own escape hatch for exactly this, since a keyword argument matching one of those names is always bound to the parameter, never reaching the indexers. Passing both raises.

refine_names
refine_names(*names: str | None) -> Self

Return a view with names assigned to (only) the unnamed axes.

Naming an already-named axis to a different name is an error; a given None keeps the current name. A single ... keeps the names of the axes it spans. Self-managed (not the builtin op).

align_to
align_to(*names: str) -> Self

Return a view with the axes permuted into the given name order.

A single ... stands for all the other axes, in their current order (e.g. x.align_to(..., "channel")). Self-managed.

align_as
align_as(other: XTensor) -> Self

Return a view aligned to other's named axes.

This tensor's axes are permuted into other's order, and a size-1 axis is inserted for every name that only other has. Every axis of self must be named and present in other. Self-managed.

acos
acos(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.acos: behaves like torch.acos, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.acos for the full numerical behaviour.

acosh
acosh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.acosh: behaves like torch.acosh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.acosh for the full numerical behaviour.

add
add(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.add: behaves like torch.add, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.add for the full numerical behaviour.

all
all(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.all: behaves like torch.all, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.all for the full numerical behaviour.

amax
amax(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.amax: behaves like torch.amax, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.amax for the full numerical behaviour.

amin
amin(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.amin: behaves like torch.amin, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.amin for the full numerical behaviour.

any
any(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.any: behaves like torch.any, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.any for the full numerical behaviour.

argmax
argmax(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.argmax: behaves like torch.argmax, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.argmax for the full numerical behaviour.

argmin
argmin(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.argmin: behaves like torch.argmin, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.argmin for the full numerical behaviour.

asin
asin(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.asin: behaves like torch.asin, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.asin for the full numerical behaviour.

asinh
asinh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.asinh: behaves like torch.asinh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.asinh for the full numerical behaviour.

atan
atan(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.atan: behaves like torch.atan, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.atan for the full numerical behaviour.

atan2
atan2(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.atan2: behaves like torch.atan2, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.atan2 for the full numerical behaviour.

atanh
atanh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.atanh: behaves like torch.atanh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.atanh for the full numerical behaviour.

bmm
bmm(input: tx.Any, other: tx.Any, **kwargs) -> tx.Any

Name-aware torch.bmm: behaves like torch.bmm, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.bmm for the full numerical behaviour.

broadcast_to
broadcast_to(input: XTensor, shape: tx.Sequence) -> XTensor

Name-aware torch.broadcast_to: behaves like torch.broadcast_to, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.broadcast_to for the full numerical behaviour.

cat
cat(tensors: tx.Sequence, dim: int | str = 0, **kwargs) -> XTensor

Name-aware torch.cat: behaves like torch.cat, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cat for the full numerical behaviour.

chunk
chunk(input: XTensor, chunks: int, dim: int | str = 0) -> tuple

Name-aware torch.chunk: behaves like torch.chunk, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.chunk for the full numerical behaviour.

cos
cos(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.cos: behaves like torch.cos, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cos for the full numerical behaviour.

cosh
cosh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.cosh: behaves like torch.cosh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cosh for the full numerical behaviour.

count_nonzero
count_nonzero(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.count_nonzero: behaves like torch.count_nonzero, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.count_nonzero for the full numerical behaviour.

cummax
cummax(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.cummax: behaves like torch.cummax, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cummax for the full numerical behaviour.

cummin
cummin(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.cummin: behaves like torch.cummin, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cummin for the full numerical behaviour.

cumprod
cumprod(input: XTensor, *args, **kwargs) -> XTensor

Name-aware torch.cumprod: behaves like torch.cumprod, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cumprod for the full numerical behaviour.

cumsum
cumsum(input: XTensor, *args, **kwargs) -> XTensor

Name-aware torch.cumsum: behaves like torch.cumsum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.cumsum for the full numerical behaviour.

diagonal
diagonal(input: XTensor, offset: int = 0, dim1: int | str = 0, dim2: int | str = 1) -> XTensor

Name-aware torch.diagonal: behaves like torch.diagonal, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.diagonal for the full numerical behaviour.

div
div(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.div: behaves like torch.div, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.div for the full numerical behaviour.

dstack
dstack(tensors: tx.Sequence, **kwargs) -> tx.Any

Name-aware torch.dstack: behaves like torch.dstack, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.dstack for the full numerical behaviour.

einsum
einsum(equation, *operands, **kwargs) -> <class 'torch.Tensor'>

Name-aware torch.einsum: behaves like torch.einsum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.einsum for the full numerical behaviour.

eq
eq(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.eq: behaves like torch.eq, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.eq for the full numerical behaviour.

erf
erf(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.erf: behaves like torch.erf, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.erf for the full numerical behaviour.

erfc
erfc(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.erfc: behaves like torch.erfc, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.erfc for the full numerical behaviour.

exp
exp(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.exp: behaves like torch.exp, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.exp for the full numerical behaviour.

expand
expand(input: XTensor, *sizes: int | tx.Sequence) -> XTensor

Name-aware torch.expand: behaves like torch.expand, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.expand for the full numerical behaviour.

expm1
expm1(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.expm1: behaves like torch.expm1, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.expm1 for the full numerical behaviour.

flatten
flatten(input: XTensor, start_dim: int | str = 0, end_dim: int | str = -1) -> XTensor

Name-aware torch.flatten: behaves like torch.flatten, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.flatten for the full numerical behaviour.

flip
flip(input: XTensor, dims: int | str | tx.Sequence) -> XTensor

Name-aware torch.flip: behaves like torch.flip, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.flip for the full numerical behaviour.

floor_divide
floor_divide(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.floor_divide: behaves like torch.floor_divide, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.floor_divide for the full numerical behaviour.

gather
gather(input: XTensor, dim: int | str, index: Tensor, **kwargs) -> tx.Any

Name-aware torch.gather: behaves like torch.gather, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.gather for the full numerical behaviour.

ge
ge(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.ge: behaves like torch.ge, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.ge for the full numerical behaviour.

gt
gt(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.gt: behaves like torch.gt, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.gt for the full numerical behaviour.

hstack
hstack(tensors: tx.Sequence, **kwargs) -> tx.Any

Name-aware torch.hstack: behaves like torch.hstack, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.hstack for the full numerical behaviour.

hypot
hypot(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.hypot: behaves like torch.hypot, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.hypot for the full numerical behaviour.

index_add
index_add(input: XTensor, dim: int | str, index: Tensor, source: Tensor, *, alpha: tx.Any = 1, **kwargs) -> tx.Any

Name-aware torch.index_add: behaves like torch.index_add, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.index_add for the full numerical behaviour.

index_copy
index_copy(input: XTensor, dim: int | str, index: Tensor, source: Tensor, **kwargs) -> tx.Any

Name-aware torch.index_copy: behaves like torch.index_copy, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.index_copy for the full numerical behaviour.

index_fill
index_fill(input: XTensor, dim: int | str, index: Tensor, value: tx.Any, **kwargs) -> tx.Any

Name-aware torch.index_fill: behaves like torch.index_fill, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.index_fill for the full numerical behaviour.

index_select
index_select(input: XTensor, dim: int | str, index: Tensor) -> tx.Any

Name-aware torch.index_select: behaves like torch.index_select, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.index_select for the full numerical behaviour.

kthvalue
kthvalue(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.kthvalue: behaves like torch.kthvalue, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.kthvalue for the full numerical behaviour.

le
le(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.le: behaves like torch.le, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.le for the full numerical behaviour.

log
log(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.log: behaves like torch.log, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.log for the full numerical behaviour.

log10
log10(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.log10: behaves like torch.log10, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.log10 for the full numerical behaviour.

log1p
log1p(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.log1p: behaves like torch.log1p, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.log1p for the full numerical behaviour.

log2
log2(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.log2: behaves like torch.log2, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.log2 for the full numerical behaviour.

log_softmax
log_softmax(input: XTensor, *args, **kwargs) -> XTensor

Name-aware torch.log_softmax: behaves like torch.log_softmax, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.log_softmax for the full numerical behaviour.

logcumsumexp
logcumsumexp(input: XTensor, *args, **kwargs) -> XTensor

Name-aware torch.logcumsumexp: behaves like torch.logcumsumexp, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.logcumsumexp for the full numerical behaviour.

logical_and
logical_and(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.logical_and: behaves like torch.logical_and, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.logical_and for the full numerical behaviour.

logical_or
logical_or(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.logical_or: behaves like torch.logical_or, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.logical_or for the full numerical behaviour.

logical_xor
logical_xor(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.logical_xor: behaves like torch.logical_xor, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.logical_xor for the full numerical behaviour.

logsumexp
logsumexp(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.logsumexp: behaves like torch.logsumexp, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.logsumexp for the full numerical behaviour.

lt
lt(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.lt: behaves like torch.lt, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.lt for the full numerical behaviour.

masked_select
masked_select(input: XTensor, mask: Tensor, **kwargs) -> tx.Any

Name-aware torch.masked_select: behaves like torch.masked_select, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.masked_select for the full numerical behaviour.

matmul
matmul(input: tx.Any, other: tx.Any, **kwargs) -> tx.Any

Name-aware torch.matmul: behaves like torch.matmul, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.matmul for the full numerical behaviour.

max
max(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.max: behaves like torch.max, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.max for the full numerical behaviour.

maximum
maximum(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.maximum: behaves like torch.maximum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.maximum for the full numerical behaviour.

mean
mean(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.mean: behaves like torch.mean, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.mean for the full numerical behaviour.

median
median(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.median: behaves like torch.median, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.median for the full numerical behaviour.

min
min(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.min: behaves like torch.min, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.min for the full numerical behaviour.

minimum
minimum(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.minimum: behaves like torch.minimum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.minimum for the full numerical behaviour.

mm
mm(input: tx.Any, other: tx.Any, **kwargs) -> tx.Any

Name-aware torch.mm: behaves like torch.mm, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.mm for the full numerical behaviour.

mode
mode(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.mode: behaves like torch.mode, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.mode for the full numerical behaviour.

moveaxis
moveaxis(input: XTensor, source, destination) -> XTensor

Name-aware torch.moveaxis: behaves like torch.moveaxis, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.moveaxis for the full numerical behaviour.

movedim
movedim(input: XTensor, source, destination) -> XTensor

Name-aware torch.movedim: behaves like torch.movedim, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.movedim for the full numerical behaviour.

mul
mul(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.mul: behaves like torch.mul, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.mul for the full numerical behaviour.

nanmean
nanmean(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.nanmean: behaves like torch.nanmean, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.nanmean for the full numerical behaviour.

nansum
nansum(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.nansum: behaves like torch.nansum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.nansum for the full numerical behaviour.

narrow
narrow(input: XTensor, dim: int | str, start: int, length: int) -> tx.Any

Name-aware torch.narrow: behaves like torch.narrow, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.narrow for the full numerical behaviour.

ne
ne(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.ne: behaves like torch.ne, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.ne for the full numerical behaviour.

nonzero
nonzero(input: XTensor, **kwargs) -> tx.Any

Name-aware torch.nonzero: behaves like torch.nonzero, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.nonzero for the full numerical behaviour.

norm
norm(input, *args, **kwargs)

Name-aware torch.norm: behaves like torch.norm, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.norm for the full numerical behaviour.

permute
permute(input: XTensor, *dims: int | str | tuple) -> XTensor

Name-aware torch.permute: behaves like torch.permute, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.permute for the full numerical behaviour.

pow
pow(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.pow: behaves like torch.pow, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.pow for the full numerical behaviour.

prod
prod(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.prod: behaves like torch.prod, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.prod for the full numerical behaviour.

remainder
remainder(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.remainder: behaves like torch.remainder, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.remainder for the full numerical behaviour.

reshape
reshape(input: XTensor, *shape: int | tuple[int, ...]) -> XTensor

Name-aware torch.reshape: behaves like torch.reshape, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.reshape for the full numerical behaviour.

roll
roll(input: XTensor, shifts: int | tx.Sequence, dims: int | str | tx.Sequence | None = None) -> XTensor

Name-aware torch.roll: behaves like torch.roll, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.roll for the full numerical behaviour.

scatter
scatter(input: XTensor, dim: int | str, index: Tensor, *args, **kwargs) -> tx.Any

Name-aware torch.scatter: behaves like torch.scatter, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.scatter for the full numerical behaviour.

scatter_add
scatter_add(input: XTensor, dim: int | str, index: Tensor, src: Tensor, **kwargs) -> tx.Any

Name-aware torch.scatter_add: behaves like torch.scatter_add, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.scatter_add for the full numerical behaviour.

select
select(input: XTensor, dim: int | str, index: int) -> tx.Any

Name-aware torch.select: behaves like torch.select, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.select for the full numerical behaviour.

sigmoid
sigmoid(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.sigmoid: behaves like torch.sigmoid, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sigmoid for the full numerical behaviour.

sin
sin(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.sin: behaves like torch.sin, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sin for the full numerical behaviour.

sinh
sinh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.sinh: behaves like torch.sinh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sinh for the full numerical behaviour.

softmax
softmax(input: XTensor, *args, **kwargs) -> XTensor

Name-aware torch.softmax: behaves like torch.softmax, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.softmax for the full numerical behaviour.

sort
sort(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.sort: behaves like torch.sort, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sort for the full numerical behaviour.

split
split(input, split_size_or_sections: int | list[int], dim: <class 'int'> = 0) -> tuple[torch.Tensor, ...]

Name-aware torch.split: behaves like torch.split, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.split for the full numerical behaviour.

squeeze
squeeze(input: XTensor, dim: int | str | tx.Sequence | None = None) -> XTensor

Name-aware torch.squeeze: behaves like torch.squeeze, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.squeeze for the full numerical behaviour.

stack
stack(tensors: tx.Sequence, dim: int = 0, **kwargs) -> XTensor

Name-aware torch.stack: behaves like torch.stack, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.stack for the full numerical behaviour.

std
std(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.std: behaves like torch.std, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.std for the full numerical behaviour.

sub
sub(a: tx.Any, b: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.sub: behaves like torch.sub, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sub for the full numerical behaviour.

sum
sum(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.sum: behaves like torch.sum, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.sum for the full numerical behaviour.

swapaxes
swapaxes(input: XTensor, dim0: int | str, dim1: int | str) -> XTensor

Name-aware torch.swapaxes: behaves like torch.swapaxes, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.swapaxes for the full numerical behaviour.

swapdims
swapdims(input: XTensor, dim0: int | str, dim1: int | str) -> XTensor

Name-aware torch.swapdims: behaves like torch.swapdims, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.swapdims for the full numerical behaviour.

take_along_dim
take_along_dim(input: XTensor, indices: Tensor, dim: int | str = None, **kwargs) -> tx.Any

Name-aware torch.take_along_dim: behaves like torch.take_along_dim, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.take_along_dim for the full numerical behaviour.

tan
tan(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.tan: behaves like torch.tan, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.tan for the full numerical behaviour.

tanh
tanh(input: tx.Any, *args, **kwargs) -> tx.Any

Name-aware torch.tanh: behaves like torch.tanh, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.tanh for the full numerical behaviour.

tensordot
tensordot(a, b, dims=2, **kwargs)

Name-aware torch.tensordot: behaves like torch.tensordot, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.tensordot for the full numerical behaviour.

topk
topk(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.topk: behaves like torch.topk, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.topk for the full numerical behaviour.

transpose
transpose(input: XTensor, dim0: int | str, dim1: int | str) -> XTensor

Name-aware torch.transpose: behaves like torch.transpose, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.transpose for the full numerical behaviour.

unbind
unbind(input: XTensor, dim: int | str = 0) -> tuple

Name-aware torch.unbind: behaves like torch.unbind, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.unbind for the full numerical behaviour.

unflatten
unflatten(input: XTensor, dim: int | str, sizes: tx.Sequence) -> XTensor

Name-aware torch.unflatten: behaves like torch.unflatten, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.unflatten for the full numerical behaviour.

unsqueeze
unsqueeze(input: XTensor, dim: int) -> XTensor

Name-aware torch.unsqueeze: behaves like torch.unsqueeze, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.unsqueeze for the full numerical behaviour.

var
var(input: XTensor, *args, **kwargs) -> tx.Any

Name-aware torch.var: behaves like torch.var, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.var for the full numerical behaviour.

view
view(input: XTensor, *shape: int | tuple[int, ...]) -> XTensor

Name-aware torch.view: behaves like torch.view, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.view for the full numerical behaviour.

vstack
vstack(tensors: tx.Sequence, **kwargs) -> tx.Any

Name-aware torch.vstack: behaves like torch.vstack, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.vstack for the full numerical behaviour.

where
where(condition: Tensor, *args) -> tx.Any

Name-aware torch.where: behaves like torch.where, but this tensor's names (and coordinates, where applicable) propagate onto the result. See torch.where for the full numerical behaviour.

Functions:

xarange

xarange(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.arange, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.arange; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xempty

xempty(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.empty, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.empty; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xempty_like

xempty_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.empty_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

xeye

xeye(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.eye, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.eye; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xfill

xfill(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.full, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.full; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xfull

xfull(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.full, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.full; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xfull_like

xfull_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.full_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

xlinspace

xlinspace(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.linspace, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.linspace; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xlogspace

xlogspace(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.logspace, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.logspace; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xmatrix

xmatrix(data: Any, *, rows: Any = (...,), cols: Any = (...,), dims: Tuple[int, int] = (-2, -1), **kwargs: Any) -> XTensor

Wrap data as an XTensor with labelled "row" and "col" axes.

The matrix analogue of xvector: names the two axes in dims (the last two by default) "row" and "col" and labels them with rows / cols (a ... fills the rest unlabelled). Other XTensor keywords are forwarded, and the result is a plain XTensor.

xmeshgrid

xmeshgrid(*tensors: Any, indexing: str = 'ij', names: Optional[Sequence] = None) -> Tuple[XTensor, ...]

Like torch.meshgrid, but each output grid is a named, coordinate-carrying XTensor.

Every output spans all the input axes; xmeshgrid names those axes after the inputs (an XTensor input contributes its own axis name, or pass names= to set them) and attaches each input as the coordinate along its axis -- exactly the coordinate grid you usually build a meshgrid for:

y = xarange(3, names=("y",))
x = xarange(4, names=("x",))
gy, gx = xmeshgrid(y, x)          # each is ("y", "x") with y/x coords

indexing is torch.meshgrid's ("ij" (default), or "xy" which swaps the first two output axes). Inputs must be 1-D. A None axis name gets no coordinate.

xones

xones(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.ones, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.ones; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xones_like

xones_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.ones_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

xrand

xrand(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.rand, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.rand; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xrand_like

xrand_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.rand_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

xrandn

xrandn(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.randn, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.randn; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xrandn_like

xrandn_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.randn_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

xstack

xstack(tensors: Sequence, dim: Any = 0, *, name: Optional[str] = None, coords: Any = None, **kwargs: Any) -> XTensor

Like torch.stack, but lets you name (and label) the new axis.

torch.stack inserts a brand-new axis that its signature gives no way to name, so it always comes out unnamed. xstack stacks the same way and then names the inserted axis name (at position dim) and, if given, labels it with coords -- handy for stacking a list of frames into a named, coordinate-carrying axis:

xstack([r, g, b], name="channel", coords=("r", "g", "b"))

The existing axes keep whatever names and labels the operands agree on (as with a plain torch.stack). coords needs a name.

xvector

xvector(data: Any, *, channels: Any = (...,), channel_dim: int = -1, **kwargs: Any) -> XTensor

Wrap data as an XTensor with one labelled channel axis.

A one-liner over XTensor(...): names axis channel_dim (the last by default) "channel" and labels it with channels (a ... in the labels fills the rest with unlabelled positions). Any other XTensor keyword (names=, coords=, unit=, ...) is forwarded.

The result is a plain XTensor, not a distinct type -- so a reduction or selection that drops the channel axis just returns a normal XTensor, and the value is never a "vector" that has lost its vector axis.

xzeros

xzeros(*args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.zeros, but returns an XTensor.

Positional and extra keyword arguments are forwarded to torch.zeros; pass any of names= / axes= / coords= / unit= to name, describe, label, and unit the axes of the result.

xzeros_like

xzeros_like(input: tx.Any, *args: tx.Any, **kwargs: tx.Any) -> XTensor

Like torch.zeros_like, but returns an XTensor.

When input is an XTensor, the result inherits its names, coordinates, descriptors, and unit; pass names= / axes= / coords= / unit= to override any of them.

as_xtensor

as_xtensor(value: Any, *, dtype: Any = None, device: Any = None, unit: Any = _UNSET, names: Any = _UNSET, coords: Any = _UNSET) -> XTensor

Coerce value (a bare Python number, a plain Tensor, or an XTensor) into an XTensor -- the XTensor analogue of torch.as_tensor: graph-safe (torch.as_tensor(value) with no dtype=/device= is a strict identity passthrough for an already-a-tensor value -- the same object, never a detaching copy, unlike torch.tensor(existing_tensor)'s well-known footgun of silently returning a fresh, non-differentiable leaf), and metadata-preserving: unit/names/coords ride through untouched unless a keyword explicitly overrides them -- mirroring how torch.as_tensor(t, dtype=..., device=...) only converts what you pass. A given override replaces wholesale, never merges (coords={...} discards whatever coordinates value already had, rather than combining the two).

dtype=/device= extend torch.as_tensor's own conversion, applied before the metadata is settled (so e.g. an axis-typed vs. numeric dtype affects nothing about the labels themselves). None (the default for both) means "leave as is" -- the same convention torch.as_tensor and .to() use.

A genuine dtype/device conversion always keeps the result's metadata: plain torch.as_tensor(an_xtensor, dtype=...) silently degrades to a plain Tensor whenever it actually has to convert something, stripping every bit of metadata in the process -- as_xtensor avoids that pitfall.

value's own tensor is never mutated: when nothing is overridden and value is already an XTensor, it is returned as-is (the same object, metadata included); otherwise the result is always a fresh view (no data copy) before any override is applied, so overriding e.g. unit= never reaches back and changes value's own unit as a side effect.

is_xtensor

is_xtensor(obj: Any) -> bool

Whether obj is an XTensor (the XTensor analogue of torch.is_tensor).