{"id":18501576,"url":"https://github.com/const-ae/einsum","last_synced_at":"2025-04-09T18:33:10.525Z","repository":{"id":51342368,"uuid":"274106728","full_name":"const-ae/einsum","owner":"const-ae","description":"Einstein Summation for Arrays in R","archived":false,"fork":false,"pushed_at":"2023-08-31T08:32:37.000Z","size":92,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-23T20:36:59.570Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://const-ae.github.io/einsum/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/const-ae.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-22T10:25:21.000Z","updated_at":"2024-11-15T04:14:16.000Z","dependencies_parsed_at":"2024-11-06T13:54:30.004Z","dependency_job_id":"666dd938-57ae-436f-8097-c8fdaf7bd71e","html_url":"https://github.com/const-ae/einsum","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Feinsum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Feinsum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Feinsum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Feinsum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/const-ae","download_url":"https://codeload.github.com/const-ae/einsum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248087892,"owners_count":21045606,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T13:54:20.230Z","updated_at":"2025-04-09T18:33:10.502Z","avatar_url":"https://github.com/const-ae.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\nset.seed(1)\n```\n\n# einsum\n\n\u003c!-- badges: start --\u003e\n[![R build status](https://github.com/const-ae/einsum/workflows/R-CMD-check/badge.svg)](https://github.com/const-ae/einsum/actions)\n[![Codecov test coverage](https://codecov.io/gh/const-ae/einsum/branch/master/graph/badge.svg)](https://app.codecov.io/gh/const-ae/einsum?branch=master)\n\u003c!-- badges: end --\u003e\n\n[Einstein summation](https://en.wikipedia.org/wiki/Einstein_notation) is a concise mathematical notation that \nimplicitly sums over repeated indices of n-dimensional arrays. Many ordinary\nmatrix operations (e.g., transpose, matrix multiplication, scalar product, 'diag()', trace, etc.)\ncan be written using Einstein notation. The notation is particularly convenient for \nexpressing operations on arrays with more than two dimensions because the \nrespective operators ('tensor products') might not have a standardized name.\n\n## Installation\n\nYou can install the package from [CRAN](https://CRAN.R-project.org/package=einsum) with:\n``` r\ninstall.packages(\"einsum\")\n```\nor if you want to use the development version from [GitHub](https://github.com/einsum):\n``` r\n# install.packages(\"devtools\")\ndevtools::install_github(\"const-ae/einsum\")\n```\n\n\n## Example\n\nLoad the package:\n\n```{r}\nlibrary(einsum)\n```\n\n\nLet's make two matrices:\n\n```{r}\nmat1 \u003c- matrix(rnorm(n = 8 * 4), nrow = 8, ncol = 4)\nmat2 \u003c- matrix(rnorm(n = 4 * 4), nrow = 4, ncol = 4)\n```\n\nWe can use `einsum()` to calculate the matrix product\n```{r}\neinsum(\"ij, jk -\u003e ik\", mat1, mat2)\n```\nwhich produces the same as the standard matrix multiplication\n```{r}\nmat1 %*% mat2\n```\nThe matrix multiplication example is straightforward, and there is little benefit of using the Einstein notation over the more familiar matrix product expression. Furthermore, 'einsum' is a lot slower. \n\nHowever, 'einsum' truly shines when working with more than 2-dimensional arrays, where it can be difficult to figure out the correct kind of tensor product:\n```{r}\n# Make three n-dimensional arrays\narr1 \u003c- array(rnorm(3 * 9 * 2), dim = c(3, 9, 2))\narr2 \u003c- array(rnorm(2 * 5), dim = c(2, 5))\narr3 \u003c- array(rnorm(9 * 3), dim = c(9, 3))\n# Sum across axes a, b, and c\neinsum(\"abc, cd, ba -\u003e d\", arr1, arr2, arr3)\n```\nThe equivalent expression using tensor products (which are not intuitive) would look like this:\n```{r}\ntensor::tensor(tensor::tensor(arr1, arr2, alongA = 3, alongB = 1), arr3, alongA = c(2,1), alongB = c(1, 2))\n```\n\n\nIf you need to do the same computation repeatedly, you can use `einsum_generator()`, which generates and compiles an efficient C++ function for that calculation (to see the function code, set `compile_function=FALSE`). It can take a few seconds to compile the function, but the returned function can be one or two orders of magnitude faster than `einsum()`.\n\n```{r}\n# einsum_generator returns a function\narray_prod \u003c- einsum_generator(\"abc, cd, ba -\u003e d\")\narray_prod(arr1, arr2, arr3)\n```\n\n\n```{r}\nbench::mark(\n  tensor = tensor::tensor(tensor::tensor(arr1, arr2, alongA = 3, alongB = 1), \n                          arr3, alongA = c(2,1), alongB = c(1, 2)),\n  einsum = einsum(\"abc, cd, ba -\u003e d\", arr1, arr2, arr3),\n  einsum_generator = array_prod(arr1, arr2, arr3)\n)\n```\n\nLastly, you can also generate C++ code if you need an efficient implementation of some function, which you could (with proper credit) for example paste into your R package:\n```{r}\n# The C++ code underlying the tensor product\ncat(einsum_generator(\"abc, cd, ba -\u003e d\", compile_function = FALSE))\n```\n\n\n\n# Credit\n\nThis package is inspired by the [einsum](https://numpy.org/doc/stable/reference/generated/numpy.einsum.html) function in NumPy.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconst-ae%2Feinsum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconst-ae%2Feinsum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconst-ae%2Feinsum/lists"}