Title: Flexible, Powerful, and Readable Tensor Operations
Version: 0.2.1
Maintainer: Qile Yang <qile.yang@berkeley.edu>
Description: Perform tensor operations using a concise yet expressive syntax inspired by the Python library of the same name. Reshape, rearrange, and combine multidimensional arrays for scientific computing, machine learning, and data analysis. Einops simplifies complex manipulations, making code more maintainable and intuitive. The original implementation is demonstrated in Rogozhnikov (2022) https://openreview.net/forum?id=oapKSVM2bcj.
License: MIT + file LICENSE
Encoding: UTF-8
RoxygenNote: 7.3.2
URL: https://github.com/Qile0317/einops, https://qile0317.github.io/einops/
BugReports: https://github.com/Qile0317/einops/issues
Imports: assertthat, FastUtils, glue, magrittr, r2r, R6, roperators
Suggests: abind, grid, imager, knitr, lifecycle, lintr, lobstr, rmarkdown, spelling, testthat (≥ 3.0.0), torch, zeallot
Config/testthat/edition: 3
VignetteBuilder: knitr
Depends: R (≥ 3.5)
LazyData: true
Language: en-US
NeedsCompilation: no
Packaged: 2025-08-29 22:24:54 UTC; qile
Author: Qile Yang ORCID iD [cre, aut, cph]
Repository: CRAN
Date/Publication: 2025-09-03 21:40:08 UTC

einops: Flexible, Powerful, and Readable Tensor Operations

Description

Perform tensor operations using a concise yet expressive syntax inspired by the Python library of the same name. Reshape, rearrange, and combine multidimensional arrays for scientific computing, machine learning, and data analysis. Einops simplifies complex manipulations, making code more maintainable and intuitive. The original implementation is demonstrated in Rogozhnikov (2022) https://openreview.net/forum?id=oapKSVM2bcj.

Author(s)

Maintainer: Qile Yang qile.yang@berkeley.edu (ORCID) [copyright holder]

See Also

Useful links:


Pipe operator

Description

See magrittr::%>% for details.

Usage

lhs %>% rhs

Arguments

lhs

A value or the magrittr placeholder.

rhs

A function call using the magrittr semantics.

Value

The result of calling rhs(lhs).


Create an AddOnlyOrderedMap instance

Description

This function initializes a new list-like object using the specified keys and values if provided. The resulting map preserves the order of insertion and does not allow modification or removal of existing entries.

The AddOnlyOrderedMap can be interacted with exactly like a regular list, possessing methods for [, [[, ⁠[<-⁠, and ⁠[[<-⁠ with the same behaviour, except that NULL cannot be passed in since removal is not permitted.

The keys() generic is defined for this class, which will return a list of the keys in their insertion order. The has_key() generic is also defined for this class, returning TRUE/FALSE if a key exists. Lastly, the values() generic is defined to get all values in insertion order.

Usage

AddOnlyOrderedMap(
  keys = NULL,
  values = NULL,
  key_validator = Negate(is.null),
  val_validator = Negate(is.null)
)

Arguments

keys

Optional list. A vector of keys to initialize the map with. Can be any R object. It is assumed that all keys are unique, otherwise the behaviour is undefined. This CANNOT be a scalar value. If that is desired, wrap it in a list().

values

Optional list. An iterable vector of values corresponding to the keys. This CANNOT be a scalar value. If that is desired, wrap it in a list().

key_validator

Optional function. A function that validates individual keys before insertion, returning TRUE if valid, FALSE otherwise.

val_validator

Optional function. A function that validates individual values before insertion, returning TRUE if valid, FALSE otherwise.

Details

The average time complexity of all operations are linear with respect to the number of insertion/query inputs, in contrast to R lists which has quadratic time complexity for the same operations.

Value

An AddOnlyOrderedMap instance


Construct an instance of an AxisNames class

Description

This is a wrapper for a list(), but the elements may only be singular character(), ConstantAstNode() or other AstNode objects. (only 1 level of nesting allowed, as its essentially another representation of a OneSidedAstNode().

Note that when using c() on an AxisNames object, when the other object is another AxisNames(), the elements of that will simply be appended to the first object. To nest (in the case of a GroupAstNode), you must append a list(AxisNames(...)) to the first object instead.

Usage

AxisNames(...)

Arguments

...

a list of elements or arbitrary number of elements

Value

an AxisNames object, which is a list with a specific class


Singleton Backend Registry, managing all available backends.

Description

Contains global backend pool, ensuring backends are only loaded if actually required.

Methods

Public methods


Method get_backend()

detect the return relevant backend from the input

Usage
BackendRegistry$get_backend(tensor)
Arguments
tensor

any supported tensor-like class

Returns

A singleton instance of a EinopsBackend() object


Method get_backend_from_type()

Get a backend instance for a specific tensor type. If the backend is not loaded, it will be instantiated.

Usage
BackendRegistry$get_backend_from_type(tensor_class)
Arguments
tensor_class

A string representing the tensor type.

Returns

An instance of the backend class for the specified tensor type.


Method register_backend()

Register a new backend singleton

Usage
BackendRegistry$register_backend(
  tensor_type,
  backend_class_thunk,
  dependencies = character(0),
  testing = FALSE,
  aliases = character(0)
)
Arguments
tensor_type

a string with the tensor type the backend supports

backend_class_thunk

a thunk()'ed EinopsBackend subclass generator

dependencies

a character vector of required package names

testing

logical flag indicating if this is a testing-only backend

aliases

a character vector of aliases for the tensor type

Returns

this object


Method unregister_backend()

Unregister a backend for a specific tensor type.

Usage
BackendRegistry$unregister_backend(tensor_type)
Arguments
tensor_type

a string with the tensor type

Returns

this object


Method add_backend_alias()

Add an alias for a backend type.

Usage
BackendRegistry$add_backend_alias(alias, tensor_type)
Arguments
alias

a string with the alias name

tensor_type

a string with the canonical tensor type

Returns

this object


Method clear_testing_backends()

Clear all testing-only backends.

Usage
BackendRegistry$clear_testing_backends()
Returns

this object


Method get_supported_types()

Get a list of all registered backend types.

Usage
BackendRegistry$get_supported_types()
Returns

A character vector of backend types.


Method get_dependencies()

given a tensor type, return the required packages

Usage
BackendRegistry$get_dependencies(tensor_type)
Arguments
tensor_type

a string with the tensor type

Returns

a character vector with required packages. Length 0 if no packages are required.


Method is_loadable()

Check if a tensor type is truly loadable, i.e., if it is registered and has no missing dependencies.

Usage
BackendRegistry$is_loadable(tensor_type)
Arguments
tensor_type

a string with the tensor type

Returns

TRUE if the tensor type is loadable, FALSE otherwise.


Create a ConstantAstNode

Description

Create a ConstantAstNode

Usage

ConstantAstNode(count, src = list())

Arguments

count

Character string representing the constant value

src

List with start position

Value

ConstantAstNode object


Create an EinopsAst root node

Description

Create an EinopsAst root node

Usage

EinopsAst(input_axes, output_axes, src)

Arguments

input_axes

List of axis nodes for the input pattern, or OneSidedAstNode()

output_axes

List of axis nodes for the input pattern, or OneSidedAstNode()

src

List with start position covering the full pattern

Value

EinopsAst object


Base Backend Class for Einops Tensor Operations

Description

Abstract base class that defines the interface for tensor operations across different frameworks. All backend implementations must inherit from this class and implement the required methods.

Methods

Public methods


Method new()

Initialize the backend and check for required packages. It is assumed that the constructor will fully load and setup all dependencies and error otherwise.

Usage
EinopsBackend$new()
Returns

A new EinopsBackend instance.


Method print()

The print method for EinopsBackend instances

Usage
EinopsBackend$print(...)
Arguments
...

arguments passed to pprint()

Returns

This object, invisibly


Method repr()

Get a string representation of this backend.

Usage
EinopsBackend$repr()
Returns

A character string describing the backend.


Method tensor_type()

Get the type of tensor this backend supports. This method should be overridden in subclasses to return the specific tensor type (e.g., "torch_tensor", "array").

Usage
EinopsBackend$tensor_type()
Returns

A string representing the tensor type.


Method preprocess()

Do any relevant preprocessing of a tensor before any operations are done on it. This should always be called before running any backend operations on a tensor

Usage
EinopsBackend$preprocess(x)
Arguments
x

The input raw tensor-like object

Returns

A preprocessed version of the input, may or may not have changed classes


Method create_tensor()

Create a tensor of the specified type with given values and dimensions.

Usage
EinopsBackend$create_tensor(values, dims, ...)
Arguments
values

A vector of values to initialize the tensor.

dims

A numeric vector specifying the dimensions of the tensor.

...

Additional arguments for specific backend implementations.

Returns

A tensor of the specified type.


Method as_array()

Convert a tensor to a standard base::array()

Usage
EinopsBackend$as_array(x)
Arguments
x

The input tensor/array.

Returns

A standard array representation of the tensor.


Method flatten()

Return a flattened version of the tensor. Note that the order of calling as_array and flatten does matter because different frameworks may store data differently.

Usage
EinopsBackend$flatten(x)
Arguments
x

The input tensor/array

Returns

A 1 dimensional tensor


Method arange()

Usage
EinopsBackend$arange(start, stop)
Arguments
start

integer, inclusive

stop

integer, inclusive

Returns

a sequence from start to stop


Method shape()

Get the shape of a tensor. Shape should return a tuple with integers or "shape symbols" (which will evaluate to actual size).

Usage
EinopsBackend$shape(x)
Arguments
x

The input tensor/array.

Returns

A numeric vector representing the tensor shape.


Method reshape()

Reshape a tensor to the specified dimensions.

Usage
EinopsBackend$reshape(x, shape)
Arguments
x

The input tensor/array.

shape

A numeric vector specifying the new shape.

Returns

The reshaped tensor/array.


Method transpose()

Transpose a tensor along the specified axes.

Usage
EinopsBackend$transpose(x, axes)
Arguments
x

The input tensor/array.

axes

A numeric vector specifying the new axis order.

Returns

The transposed tensor/array.


Method reduce()

Reduce a tensor along specified axes using the given operation.

Usage
EinopsBackend$reduce(x, operation, axes)
Arguments
x

The input tensor/array.

operation

A character string specifying the reduction operation (e.g., "sum", "mean", "max", "min", "prod", "all", "any"), OR a two argument function, with the first argument being the tensor to modify, and the second argument being an integer list of axes to perform the reduction over.

axes

A numeric vector specifying which axes to reduce over.

Returns

The reduced tensor/array.


Method stack_on_zeroth_dimension()

Stack multiple tensors along a new zeroth dimension.

Usage
EinopsBackend$stack_on_zeroth_dimension(tensors)
Arguments
tensors

A list of tensors/arrays to stack.

Returns

A tensor/array with the input tensors stacked along dimension 1.


Method add_axis()

Add a new axis to a tensor at the specified position.

Usage
EinopsBackend$add_axis(x, new_position)
Arguments
x

The input tensor/array.

new_position

The position (1-based) where to insert the new axis.

Returns

The tensor/array with a new axis added.


Method add_axes()

Add multiple axes to a tensor and tile along specified axes.

This function adds new axes to the input tensor at the specified positions and tiles the tensor along those axes according to the provided lengths.

Usage
EinopsBackend$add_axes(x, n_axes, pos2len)
Arguments
x

The input tensor/array.

n_axes

The total number of axes after addition.

pos2len

int->int r2r::hashmap() mapping positions to lengths.

Returns

The tensor/array with new axes added and tiled as specified.


Method tile()

Tile (repeat) a tensor along each axis according to the repeat counts. The repeats vector should have the same length as the tensor's shape.

Usage
EinopsBackend$tile(x, repeats)
Arguments
x

The input tensor/array.

repeats

A numeric vector specifying how many times to repeat along each axis. Must have same length as x.shape.

Returns

The tiled tensor/array.


Method concat()

Concatenate tensors along the specified axis. Assumes identical devices, dtypes and shapes except for the selected axis.

Usage
EinopsBackend$concat(tensors, axis)
Arguments
tensors

A list of tensors/arrays to concatenate.

axis

The axis along which to concatenate (1-based).

Returns

The concatenated tensor/array.


Method is_float_type()

Check if the tensor has a floating point data type.

Usage
EinopsBackend$is_float_type(x)
Arguments
x

The input tensor/array.

Returns

A logical value indicating if the tensor is of float type.


Method layers()

Get neural network layers specific to this backend.

Usage
EinopsBackend$layers()
Returns

Backend-specific layer implementations.


Method einsum()

Perform Einstein summation on tensors.

Usage
EinopsBackend$einsum(pattern, ...)
Arguments
pattern

A character string specifying the einsum pattern.

...

Additional tensors to operate on.

Returns

The result of the einsum operation.


Constructor for an Execution Plan (CookedRecipe in the python sourcecode)

Description

Constructor for an Execution Plan (CookedRecipe in the python sourcecode)

Usage

EinopsExecutionPlan(
  init_shapes,
  axes_reordering,
  reduced_axes,
  added_axes,
  final_shapes,
  n_axes_w_added
)

Arguments

init_shapes

integer vector specifying initial tensor shapes for reshaping. Length 0 signifies nullness.

axes_reordering

integer vector specifying the order for transposing tensor axes. Length 0 signifies nullness.

reduced_axes

List of integers specifying which axes to reduce during operations. Length 0 signifies nullness.

added_axes

r2r::hashmap() mapping axis positions (int) to their lengths (int) for axes to be added.

final_shapes

list of integers specifying final tensor shapes for reshaping. Length 0 signifies nullness.

n_axes_w_added

Integer specifying the total number of axes after adding new axes.

Value

An object of class EinopsExecutionPlan, which is a list containing the execution plan for transforming tensors according to the specified recipe.


EinopsTokenSequence constructor

Description

Helper to build a token sequence (list of tokens)

Usage

EinopsTokenSequence(...)

Arguments

...

tokens or EinopsTokenSequences to include

Value

list of tokens


Create an EllipsisAstNode

Description

Create an EllipsisAstNode

Usage

EllipsisAstNode(src)

Arguments

src

List with start position

Value

EllipsisAstNode object


Create a GroupAstNode

Description

Create a GroupAstNode

Usage

GroupAstNode(children, src = list())

Arguments

children

List of axis nodes contained in this group, potentially empty

src

List with start position

Value

GroupAstNode object


Create a NamedAxisAstNode

Description

Create a NamedAxisAstNode

Usage

NamedAxisAstNode(name, src = list())

Arguments

name

Character string, the name of the axis

src

List with start position

Value

NamedAxisAstNode object


Create a OneSidedAstNode (wrapper for input/output axes lists)

Description

Create a OneSidedAstNode (wrapper for input/output axes lists)

Usage

OneSidedAstNode(...)

Arguments

...

Axis nodes (or a single list of axis nodes) If this is already a OneSidedAstNode, it is returned as is.

Value

OneSidedAstNode object


TransformRecipe S3 constructor

Description

Recipe describes actual computation pathway. Can be applied to a tensor or variable.

Usage

TransformRecipe(
  elementary_axes_lengths,
  axis_name2elementary_axis,
  input_composition_known_unknown,
  axes_permutation,
  first_reduced_axis,
  added_axes,
  output_composite_axes
)

Arguments

elementary_axes_lengths

Integer vector. List of sizes for elementary axes as they appear in the input (left) expression. This is what (after computing unknown parts) will be a shape after first transposition. This does not include any ellipsis dimensions.

axis_name2elementary_axis

r2r::hashmap() Mapping from name to position. if additional axes are provided, they should be set in prev array. The keys are unclassed AxisNames() objects, and the values are integer positions of the elementary axes.

input_composition_known_unknown

List of list(known, unknown). known and unknown are integer vectors containing axis positions. These unknown and unknown integer vectors represent an unordered set and are always sorted to help with testing. ascending order for deterministic output.

axes_permutation

Integer vector. Permutation applied to elementary axes, if ellipsis is absent.

first_reduced_axis

Integer of length 1. First position of reduced axes. Permutation puts reduced axes in the end, we only need to know the first position.

added_axes

r2r::hashmap(). Axis position -> axis index. At which positions which of elementary axes should appear.

output_composite_axes

List of integer vectors. Ids of axes as they appear in result. Again pointers to elementary_axes_lengths, only used to infer result dimensions.

Value

An object of class 'TransformRecipe'.


Create an UnderscoreAstNode

Description

Create an UnderscoreAstNode

Usage

UnderscoreAstNode(src = list())

Arguments

src

List with start position

Value

UnderscoreAstNode object


Vector Merging

Description

Add elements to a vector.

Usage

append(x, values, after = length(x), ...)

Arguments

x

the vector the values are to be appended to.

values

to be included in the modified vector.

after

a subscript, after which the values are to be appended.

...

Additional arguments passed to or from other methods.

Value

A vector containing the values in x with the elements of values appended after the specified element of x.

References

Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.

Examples

append(1:5, 0:1, after = 3)

Apply a TransformRecipe to a Tensor

Description

This function applies a TransformRecipe to a tensor, performing rearrangement and reduction as specified by the recipe.

TODO docs for which parts of the compilation pipeline this is.

Usage

apply_recipe(backend, recipe, tensor, reduction_type, axes_lengths)

Arguments

backend

The EinopsBackend() to use for tensor operations.

recipe

A TransformRecipe() that specifies how to transform the tensor.

tensor

A tensor to be transformed

reduction_type

A character of length 1 that specifies the type of reduction to apply.

axes_lengths

TODO check - I think its just an integer vector?

Value

A tensor that has been transformed according to the recipe, with the same type (if possible) as the input tensor.


Convert an AstNode into an AxisNames() object

Description

Convert an AstNode into an AxisNames() object

Usage

as_axis_names(ast, ...)

Arguments

ast

the AstNode input

...

other args

Value

an AxisNames() object of the axes in order


Convert an object to a list of iterables (lists)

Description

This function converts an object into a list of iterables, where each iterable is a list of elements. The function is generic and can be extended for different classes.

Usage

as_iterables(x, ...)

Arguments

x

the input object to be converted

...

additional arguments (not used)

Value

a list of iterables, where each iterable is a list of elements

AxisNames

This method converts an AxisNames object into a list of iterables. Each element in the AxisNames is processed to extract its name or constant value. If the element is a ConstantAstNode with a count of 1, it is converted to an empty list. Otherwise, it is wrapped in a list. If the element is a NamedAxisAstNode, its name is extracted. Regular AxisNames that are nested will be unclassed


Reconstruct all actual parameters using shape.

Description

This implements ⁠_reconstruct_from_shape_uncached⁠ from the python implementation of einops. In the future, a cached version may be implemented.

Usage

create_execution_plan(recipe, shape, axes_dims)

Arguments

recipe

a populated TransformRecipe() object

shape

A vector of integers representing the shape of the tensor.

axes_dims

A named list of axes names to their dimensions/lengths. May also be an empty list.

Value

An EinopsExecutionPlan object that contains the execution plan for transforming tensors according to the specified recipe and shape.


Perform Einstein-style tensor operations

Description

A unified interface for rearranging, reducing, and repeating tensor dimensions using Einstein notation-inspired expressions. This was directly adapted from the python einop package: https://github.com/cgarciae/einop

einop() auto detects the operation type based on the provided expression:

Note that there are ongoing debates about the use of this function purely from the perspective of code readability and maintainability: https://github.com/arogozhnikov/einops/issues/84. Generally, some argue that the descriptive names of rearrange, reduce, and repeat encourage good practices, while others think that semantically einop() actually makes it clearer what the operation is doing, as opposed to mandating the use of these commonly used function names across many packages.

Usage

einop(
  x,
  expr,
  reduction = NULL,
  ...,
  .row_major = getOption("einops_row_major", FALSE)
)

Arguments

x

tensor: array, matrix, or list of arrays of the same shape and type

expr

string: reduction pattern

reduction

A string specifying the reduction operation (e.g., "mean", "sum", "max"). Required for reduce operations, ignored for rearrange and repeat operations.

...

either corresponding axes lengths or a single list of them.

.row_major

[Experimental] logical: whether to use row-major order for the output tensor. If TRUE, the operation is performed in row-major order, but the output will be in whatever order the parent framework uses (e.g. column-major for base::array()).

Value

A tensor with dimensions transformed according to the expression

Examples

if (requireNamespace("abind", quietly = TRUE)) {

# load a 3d tensor representing an rgb image
x <- get(data("einops_image"))[1, , , ]

# Rearrange dimensions
einop(x, "h w c -> c h w")

# Reduce dimensions
einop(x, "h w c -> h w", "mean")

# Repeat dimensions
einop(x[, , 1], "h w -> h w c", c = 3)

}


Allows reordering elements and repeating them in arbitrary combinations.

Description

This operation includes functionality of repeat, tile, and broadcast functions.

Usage

einops.repeat(x, expr, ..., .row_major = getOption("einops_row_major", FALSE))

`repeat`(x, expr, ..., .row_major = getOption("einops_row_major", FALSE))

Arguments

x

tensor: array, matrix, or list of arrays of the same shape and type

expr

string: reduction pattern

...

either corresponding axes lengths or a single list of them.

.row_major

[Experimental] logical: whether to use row-major order for the output tensor. If TRUE, the operation is performed in row-major order, but the output will be in whatever order the parent framework uses (e.g. column-major for base::array()).

Details

When composing axes, C-order enumeration is used (consecutive elements have different last axis). Find more examples in the vignettes.

Value

tensor of the same type as input, with dimensions according to output pattern

Why can't the function be called as ⁠repeat()⁠?

repeat is a reserved keyword in R that acts the same as ⁠while(TRUE)⁠, and has no way of being overridden. Hence, this function can only be called as einops.repeat() or using backticks as `repeat`().

Examples

if (requireNamespace("abind", quietly = TRUE)) {

set.seed(42)
# a grayscale image (of shape height x width)
image <- array(rnorm(30 * 40), dim = c(30, 40))

# change it to RGB format by repeating in each channel
output <- einops.repeat(image, 'h w -> h w c', c = 3)
# Visualize the output
as_image_tensor(output)

# repeat image 2 times along height (vertical axis)
output <- einops.repeat(image, 'h w -> (r h) w', r = 2)

# repeat image 2 times along height and 3 times along width
output <- einops.repeat(image, 'h w -> (h2 h) (w3 w)', h2 = 2, w3 = 3)

# convert each pixel to a small square 2x2, i.e. upsample an image by 2x
output <- einops.repeat(image, 'h w -> (h h2) (w w2)', h2 = 2, w2 = 2)

# 'pixelate' an image first by downsampling by 2x, then upsampling
downsampled <- reduce(image, '(h h2) (w w2) -> h w', 'mean', h2 = 2, w2 = 2)
output <- einops.repeat(downsampled, 'h w -> (h h2) (w w2)', h2 = 2, w2 = 2)
as_image_tensor(einops.repeat(output, 'h w -> h w 3'))

}


Example 4D Image Tensor for Einops

Description

An image_tensor() object that is a super thin wrapper around a 4D base::array(), representing image data in the format "b h w c" (batch, height, width, channels). The actual image data is 6 black letters on differently colored backgrounds, spelling out the word "einops". When printing this object in the terminal it will automatically plot the images. To subset, use the [ operator, and when used with a single index, it will return a single image tensor.

Usage

einops_image

Format

An image_tensor() object with 6 images, each of size 96 x 96 pixels, with 3 color channels (RGB). The images are stored in a 4D array with dimensions (6, 96, 96, 3).

Examples

data("einops_image")
for (i in seq_len(6)) print(einops_image[i, , , ])

Expand ellipses of an EinopsAst

Description

Helper for prepare_transformation_recipe().

This function expands each relevant ellipsis ast node in-place into a sequence of NamedAxisAstNode nodes, where each node will have a name like "...1", "...2", etc. and an empty src list.

Also does some further validation of the ellipses syntax using ndim.

Usage

expand_ellipsis(einops_ast, ndim)

Arguments

einops_ast

an EinopsAst

ndim

integer. Number of dimensions in the input tensor

Value

an expanded EinopsAst with ellipses expanded


Find the arrow in a token sequence

Description

Find the arrow in a token sequence

Usage

find_top_level_arrow_index(tokens)

Arguments

tokens

EinopsTokenSequence object

Value

one-indexed Integer position of the arrow token


Main function to detect and return backend

Description

Main function to detect and return backend

Usage

get_backend(tensor)

Arguments

tensor

any supported tensor-like object

Value

An instance of a EinopsBackend() class. Every returned object is a singleton, so the same object will be returned for the same tensor type.


Given a OneSidedAstNode object, get unique identifiers

Description

get an unordered list, representing a set of all unique identifiers on one side of the expression. Named nodes become the character representing its name, ConstantAstNode nodes are just themselves, aside from 1 which is ignored. GroupAstNode nodes are flattened, and EllipsisAstNode nodes are ignored.

Usage

get_identifiers(ast, ...)

Arguments

ast

the Abstract Syntax Tree (AST) of the einops expression positions to the ConstantAstNode objects in the output. This will REMOVE all other elements in the src list.

...

additional arguments (not used)

Value

an AxisNames() of unique identifiers


Get the ordered axis names from a OneSidedAstNode, removing all nesting.

Description

Get the ordered axis names from a OneSidedAstNode, removing all nesting.

Usage

get_ordered_axis_names(ast, ...)

Arguments

ast

OneSidedAstNode object

...

additional arguments (not used)

Value

a list() of axis names


get flat list of all AstNodes in order, including children of GroupAstNodes.

Description

get flat list of all AstNodes in order, including children of GroupAstNodes.

Usage

get_ungrouped_nodes(ast, ...)

Arguments

ast

An AstNode object

Value

A flat list of AstNodes


Image Tensor: A thin wrapper around 2-4D arrays

Description

The image_tensor class provides a convenient way to work with image data in tensor format. It extends the base array class and provides methods for conversion to/from various image formats, plotting, and printing.

An image_tensor object represents image data in the format "h w c" (height, width, channels) for single images, or "b h w c" (batch, height, width, channels) for batches of images, which is a common format for deep learning frameworks. It also can be a 2D array, in which case it is treated as a black and white image and shown as such.

The main utility of wrapping image data in the image_tensor class is that printing of the object will automatically display the image as a plot, as long as the imager package is installed. Otherwise it will simply print the dimension of the image.

Usage

as_image_tensor(x)

image_tensor(x)

Arguments

x

An object to convert to or from image_tensor format.

Details

The image_tensor class provides the following methods (and more):

Value

Format

An image_tensor object is an array with dimensions in "h w c" format for single images, or "b h w c" format for batches of images:

Options

The following options control the default behavior of image_tensor methods:

Examples

# create from a matrix (grayscale)
img <- image_tensor(matrix(1:9, 3, 3))
print(img)
print(img[1:2, 1:2])

# create from a 3D array (RGB image)
img_rgb <- as_image_tensor(array(runif(27), dim = c(3, 3, 3)))
print(img_rgb)


Lexically analyze einops pattern into structured tokens

Description

Lexically analyze einops pattern into structured tokens

Usage

lex(pattern)

Arguments

pattern

character string with einops pattern

Value

list of token objects with type, value, start, end fields


Parse a sequence of axis tokens

Description

Parse a sequence of axis tokens

Usage

parse_axes_iter(tokens)

Arguments

tokens

List of tokens representing one side of the pattern

Value

List of AST nodes


Parse einops pattern into AST

Description

In the python implementation, they preprocess all 1's into () and then parse it into the equivalent of a GroupAstNode. Here, we won't do that

Usage

parse_einops_ast(tokens)

Arguments

tokens

EinopsTokenSequence object from the lexer

Value

EinopsAst object


Parse a one-sided einops pattern into OneSidedAstNode

Description

Parse a one-sided einops pattern into OneSidedAstNode

Usage

parse_onesided_ast(tokens)

Arguments

tokens

EinopsTokenSequence object from the lexer (no arrow expected)

Value

OneSidedAstNode object


Parse a tensor shape to dictionary mapping axes names to their lengths.

Description

Use underscore to skip the dimension in parsing.

Usage

parse_shape(x, expr, ...)

Arguments

x

tensor of any supported framework

expr

character of length 1, space separated names for axes, underscore means skip axis

...

additional arguments passed to methods

Value

named list, maps axes names to their lengths

Examples

if (requireNamespace("abind", quietly = TRUE)) {

# Use underscore to skip the dimension in parsing.
x <- array(0, dim = c(2, 3, 5, 7))
parse_shape(x, 'batch _ h w')

# `parse_shape` output can be used to specify axes_lengths for other
# operations:
y <- array(0, dim = 700)
shape_info <- parse_shape(x, 'b _ h w')
# rearrange(y, '(b c h w) -> b c h w', shape_info) would give shape
# (2, 10, 5, 7)

}


Pretty Print

Description

This is a convenience function that prints the repr() of an object. It is similar to python's pprint.pprint(). Usually, to ensure that an object is displayed in the terminal using its pprint format, just define a print.that_object_class method that calls pprint().

Usage

pprint(x, ...)

Arguments

x

Object to pretty print

...

Additional arguments passed to repr()

Value

The input object, invisibly


Create the Transformation Recipe for an einops call

Description

This function does the following parts of the einops 'compilation' pipeline:

  1. Lexing: tokenizing the input expression string

  2. Parsing: converting the tokens into an Abstract Syntax Tree (AST)

  3. Syntactic Analysis:

    • operation-based AST validation pass

    • Compile syntactic info for intermediate representation (IR).

  4. IR generation: return the TransformRecipe() object.

Usage

prepare_transformation_recipe(
  expr,
  func,
  axes_names,
  ndim,
  reverse_groups = FALSE
)

Arguments

expr

The input einops expression string

func

The string/function indicating the reduction operation

axes_names

user defined axis names as a character() vector.

ndim

count for the number of dimensions of the input tensor

reverse_groups

[Experimental] logical: whether to reverse the order of the axes in each group.

Value

a populated TransformRecipe() object


Reader-friendly smart element reordering for multidimensional tensors.

Description

This operation includes functionality of transpose (axes permutation), reshape (view), squeeze, unsqueeze, stack, concatenate and other operations.

Usage

rearrange(x, expr, ..., .row_major = getOption("einops_row_major", FALSE))

einops.rearrange(
  x,
  expr,
  ...,
  .row_major = getOption("einops_row_major", FALSE)
)

Arguments

x

tensor: array, matrix, or list of arrays of the same shape and type

expr

string: reduction pattern

...

either corresponding axes lengths or a single list of them.

.row_major

[Experimental] logical: whether to use row-major order for the output tensor. If TRUE, the operation is performed in row-major order, but the output will be in whatever order the parent framework uses (e.g. column-major for base::array()).

Details

When composing axes, C-order enumeration is used (consecutive elements have different last axis). Find more examples in the vignettes.

Value

tensor of the same type as input, with dimensions according to output pattern

Examples

if (requireNamespace("abind", quietly = TRUE)) {

# suppose we have a set of 32 images in "h w c" format (height-width-channel)
images <- lapply(1:32, function(i) {
    as_image_tensor(array(rnorm(30*40*3), dim = c(30, 40, 3)))
})

# stacked and reordered axes to "b c h w" format
y <- rearrange(images, 'b h w c -> b c h w')

# concatenate images along height (vertical axis), 960 = 32 * 30
y <- rearrange(images, 'b h w c -> (b h) w c')

# concatenated images along horizontal axis, 1280 = 32 * 40
y <- rearrange(images, 'b h w c -> h (b w) c')

# flattened each image into a vector, 3600 = 30 * 40 * 3
y <- rearrange(images, 'b h w c -> b (c h w)')

# split each image into 4 smaller quadrants, 128 = 32 * 2 * 2
y <- rearrange(
    images, 'b (h1 h) (w1 w) c -> (b h1 w1) h w c', h1 = 2, w1 = 2
)

# space-to-depth operation
y <- rearrange(
    images, 'b (h h1) (w w1) c -> b h w (c h1 w1)', h1 = 2, w1 = 2
)

}


Rearrangement and reduction in one step

Description

reduce() combines rearrangement and reduction using reader-friendly notation.

Usage

reduce(x, expr, func, ..., .row_major = getOption("einops_row_major", FALSE))

einops.reduce(
  x,
  expr,
  func,
  ...,
  .row_major = getOption("einops_row_major", FALSE)
)

Arguments

x

tensor: array, matrix, or list of arrays of the same shape and type

expr

string: reduction pattern

func

string or function: one of available reductions ('min', 'max', 'sum', 'mean', 'prod', 'any', 'all'), or an R 2 argument function which takes in two arguments, with the first being the tensor, and the second being an integer array indicating the dimensions to reduce over.

...

either corresponding axes lengths or a single list of them.

.row_major

[Experimental] logical: whether to use row-major order for the output tensor. If TRUE, the operation is performed in row-major order, but the output will be in whatever order the parent framework uses (e.g. column-major for base::array()).

Value

tensor of the same type as input, with dimensions according to output pattern

Examples

if (requireNamespace("abind", quietly = TRUE)) {

set.seed(42)
# Suppose x is a 3D array: 100 x 32 x 64
x <- array(rnorm(100 * 32 * 64), dim = c(100, 32, 64))

# perform max-reduction on the first axis
# Axis t does not appear on RHS - thus we reduced over t
y <- reduce(x, 't b c -> b c', 'max')

# same as previous, but using verbose names for axes
y <- reduce(x, 'time batch channel -> batch channel', 'max')

# let's pretend now that x is a batch of images
# with 4 dims: batch=10height = 20width = 30channel = 40
x <- array(rnorm(10 * 20 * 30 * 40), dim = c(10, 20, 30, 40))

# 2d max-pooling with kernel size = 2 * 2 for image processing
y1 <- reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h2 = 2, w2 = 2)
as_image_tensor(y1)

# same as previous, using anonymous axes,
# note: only reduced axes can be anonymous
y1 <- reduce(x, 'b c (h1 2) (w1 2) -> b c h1 w1', 'max')
as_image_tensor(y1)

# adaptive 2d max-pooling to 3 * 4 grid,
# each element is max of 10x10 tile in the original tensor.
dim(reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h1 = 3, w1 = 4))
# (10, 20, 3, 4)

# Global average pooling
dim(reduce(x, 'b c h w -> b c', 'mean'))
# (10, 20)

}


Register a new backend for a tensor type

Description

Registers a backend implementation for a specific tensor type, along with any required dependencies, testing flag, and optional aliases. This function wraps the backend class in a thunk() and registers it with the backend registry.

Usage

register_backend(
  tensor_type,
  backend_class,
  dependencies = character(0),
  testing = FALSE,
  aliases = character(0)
)

Arguments

tensor_type

A string specifying the tensor type the backend supports.

backend_class

An R6Class generator for the backend (subclass of EinopsBackend). Note that this binding does not necessarily have to have a defined value at the time of calling this function.

dependencies

Optional character vector of required package names.

testing

If TRUE, indicates its only used for testing.

aliases

Optional character vector of aliases for the tensor type.

Value

Invisibly returns the backend registry object.


Python-like Representation of Objects as Strings

Description

This is an R implementation of python's repr() function. All objects will have a default repr that uses its print method. This is important because the pprint() function will always be able to give a repr-esque output of any object.

Usage

repr(x, indent = 0L, ...)

Arguments

x

Object to represent

indent

Indentation level (number of spaces)

...

Additional arguments passed to methods

Value

A character vector of class c("repr_output", "character"), each element is a line


Get the last n children of a GroupAstNode as a list of AstNodes.

Description

Get the last n children of a GroupAstNode as a list of AstNodes.

Usage

## S3 method for class 'GroupAstNode'
tail(x, n = 1, ...)

Simple thunk: wraps an input in a no-argument function

Description

Simple thunk: wraps an input in a no-argument function

Usage

thunk(input)

Arguments

input

Any R object or expression

Value

A thunk that returns the object when called with class c("thunk", "function")


Syntactically Validate the reduction operation in the einops expression

Description

Syntactically Validate the reduction operation in the einops expression

Usage

validate_reduction_operation(einops_ast, operation)

Arguments

einops_ast

the parsed Abstract Syntax Tree (AST) of the einops expression

operation

the reduction operation, either a string or a function

Value

the input einops_ast (invisibly) if the validation passes