{"id":15286697,"url":"https://github.com/iitis/symmetrictensors.jl","last_synced_at":"2025-04-13T03:42:23.312Z","repository":{"id":61799693,"uuid":"79091776","full_name":"iitis/SymmetricTensors.jl","owner":"iitis","description":"Framework for symmetric tensors","archived":false,"fork":false,"pushed_at":"2023-05-17T07:20:57.000Z","size":770,"stargazers_count":10,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-11T11:16:16.463Z","etag":null,"topics":["julia"],"latest_commit_sha":null,"homepage":null,"language":"Julia","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/iitis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2017-01-16T07:02:42.000Z","updated_at":"2024-04-03T20:43:01.000Z","dependencies_parsed_at":"2024-12-24T13:21:43.684Z","dependency_job_id":null,"html_url":"https://github.com/iitis/SymmetricTensors.jl","commit_stats":{"total_commits":274,"total_committers":10,"mean_commits":27.4,"dds":0.5766423357664234,"last_synced_commit":"c7b1833b5f0a2020f4bc7bca98ea85d6d2e191bc"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FSymmetricTensors.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FSymmetricTensors.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FSymmetricTensors.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FSymmetricTensors.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iitis","download_url":"https://codeload.github.com/iitis/SymmetricTensors.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248661090,"owners_count":21141393,"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":["julia"],"created_at":"2024-09-30T15:18:15.600Z","updated_at":"2025-04-13T03:42:23.294Z","avatar_url":"https://github.com/iitis.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SymmetricTensors.jl\n[![Coverage Status](https://coveralls.io/repos/github/iitis/SymmetricTensors.jl/badge.svg?branch=master)](https://coveralls.io/github/iitis/SymmetricTensors.jl?branch=master)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7943859.svg)](https://doi.org/10.5281/zenodo.7943859)\n\n\n\nSymmetricTensors.jl provides the `SymmetricTensors{T, N}` type used to store fully symmetric tensors in more efficient way,\nwithout most of redundant repetitions. It uses blocks of `Array{T, N}` stored in `Union{Array{Float,N}, Nothing}` structure.\nRepeated blocks are replaced by `Void`. The module introduces `SymmetricTensors{T, N}` type and some basic operations on this type.\nAs of 01/01/2017 [@kdomino](https://github.com/kdomino) is the lead maintainer of this package.\n\n## Installation\n\nWithin Julia, just use run\n\n```julia\npkg\u003e add SymmetricTensors\n```\n\nto install the files. Julia 1.0 or later is required.\n\n\n## Constructor\n\n```julia\njulia\u003e data = ones(4,4);\n\n\njulia\u003e SymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0]; nothing [1.0 1.0; 1.0 1.0]], 2, 2, 4, true)\n\n\n```\n\n## Converting\n\nFrom `Array{T, N}` to `SymmetricTensors{T, N}`\n\n```julia\njulia\u003e SymmetricTensors(data::Array{T, N}, bls::Int = 2)\n```\nwhere bls is the size of a block. It is a parameter affecting the compuational speed of cumulants. The block size must fulfill `bls ∈ {1, 2,..., dats}` where `dats = size(data, 1) = ... = size(data, N)` otherwise error is risen.\n\n\n```julia\njulia\u003e data = ones(4,4);\n\n\njulia\u003e convert(SymmetricTensor, data, 2)\nSymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0]; nothing [1.0 1.0; 1.0 1.0]], 2, 2, 4, true)\n\n```\n\nFrom `SymmetricTensors{T, N}` to `Array{T, N}`\n\n```julia\njulia\u003e Array(st::SymmetricTensors{T, N})\n```\n\nWrong block size:\n\n```\njulia\u003e SymmetricTensor(ones(4,4), 5)\nERROR: DimensionMismatch(\"bad block size 5 \u003e 4\")\n```\n\n\n## Fields\n\n- `frame::ArrayNArrays{T,N}`: stores data, where `ArrayNArrays{T,N} = Array{Union{Array{T, N}, Nothing}, N}`\n- `bls::Int`: the size of ordinary block (the same in each direction),\n- `bln::Int`: maximal number of blocks in each direction,\n- `dats::Int`: the size of data stored (the same in each direction),\n- `sqr::Bool`: if all blocks are squares (N-squares).\n\n\nSuppose we have `N = 2` and `dats = 6` and `bls = 3` hence data are symmetric matrix of size `6 x 6`. Data are stored in the form:\n\n```\n|B11   B12 | \n|null  B22 | \n```\n\nhere `bls = 2` and size of `B11`, `B12`, and `B22` are `3 x 3`. Bear in mind, that `B11` and `B22` his to be symmetric. As `B12` (the last block) is square, `sqr = True`.\n\nSuppose now `N = 2` and `dats = 5` and `bls = 3` hence data are symmetric matrix of size `5 x 5`. Data are stored in similar form:\n\n```\n|B11   B12 | \n|null  B22 | \n```\n\nhere `bls = 2` and size of `B11` is `3 x 3`, but size of `B12` is `2 x 3`, and size `B22` is `2 x 2 `. Again `B11` and `B22` his to be symmetric. As `B12` (the last block) is not square, `sqr = False`.\n\nFor `N = 3` we have analogical pyramid representation, and for `N \u003e 3` hyper-pyramid representation.\n\n\n\n## Operations\n\nElementwise addition: `+, -` is supported between many `SymmetricTensors{T, N}` while elementwise substraction: `-` between two `SymmetricTensors{T, N}`. Addition substraction multiplication and division `+, -, *, /`\nis supported between `SymmetricTensors{T, N}` and a number. \n\n```julia\njulia\u003e x = SymmetricTensor(ones(4,4));\n\njulia\u003e y = SymmetricTensor(2*ones(4,4));\n\njulia\u003e x+y\nSymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[3.0 3.0; 3.0 3.0] [3.0 3.0; 3.0 3.0]; #undef [3.0 3.0; 3.0 3.0]], 2, 2, 4, true)\n\njulia\u003e x*10\nSymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[10.0 10.0; 10.0 10.0] [10.0 10.0; 10.0 10.0]; #undef [10.0 10.0; 10.0 10.0]], 2, 2, 4, true)\n```\n\n\nThe function diag returns a Vector{T}, of all super-diagonal elements of a SymmetricTensor.\n\n```julia\njulia\u003e data = ones(5,5,5,5);\n\njulia\u003e st = SymmetricTensor(data);\n\njulia\u003e diag(st)\n5-element Array{Float64,1}:\n 1.0\n 1.0\n 1.0\n 1.0\n 1.0\n```\n\n## Random Symmetric Tensor generation\n\nTo generate random Symmetric Tensor with random elements of typer `T` form a uniform distribution on `[0,1)` use `rand(SymmetricTensor{T, N}, n::Int, b::Int = 2)`. Here `n` denotes size of each mode and `b` denotes block size. Eg. for `N = 4` we would have `n x n x n x n` tensor.\n\n```julia\njulia\u003e using Random\n\njulia\u003e Random.seed!(42)\n\njulia\u003e x = rand(SymmetricTensor{Float64, 3}, 2)\nSymmetricTensor{Float64, 3}(Union{Nothing, Array{Float64, 3}}[[0.5331830160438613 0.4540291355871424; 0.4540291355871424 0.017686826714964354]\n\n[0.4540291355871424 0.017686826714964354; 0.017686826714964354 0.17293302893695128]], 2, 1, 2, true)\n\njulia\u003e Array(x)\n2×2×2 Array{Float64, 3}:\n[:, :, 1] =\n 0.533183  0.454029\n 0.454029  0.0176868\n\n[:, :, 2] =\n 0.454029   0.0176868\n 0.0176868  0.172933\n\n\n```\n\n```julia\njulia\u003e Random.seed!(42)\n\njulia\u003e x = rand(SymmetricTensor{Float64, 2}, 3)\nSymmetricTensor{Float64, 2}(Union{Nothing, Matrix{Float64}}[[0.5331830160438613 0.4540291355871424; 0.4540291355871424 0.017686826714964354] [0.17293302893695128; 0.9589258763297348]; nothing [0.9735659798036858]], 2, 2, 3, false)\n\njulia\u003e Array(x)\n3×3 Matrix{Float64}:\n 0.533183  0.454029   0.172933\n 0.454029  0.0176868  0.958926\n 0.172933  0.958926   0.973566\n\n```\n\n## getindex and setindex!\n\n```julia\njulia\u003e using Random\n\njulia\u003e Random.seed!(42)\n\njulia\u003e st = rand(SymmetricTensor{Float64, 2}, 2)\nSymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[0.533183 0.454029; 0.454029 0.0176868]], 2, 1, 2, true)\n\njulia\u003e st[1,2]\n0.4540291355871424\n\njulia\u003e st[2,1]\n0.4540291355871424\n\n\njulia\u003e pyramidindices(st)\n3-element Vector{Tuple{Int64, Int64}}:\n (1, 1)\n (1, 2)\n (2, 2)\n\n```\nFunction ```pyramidindices(st::SymmetricTensor)``` returns the indices of the unique element of the give symmetric tensor\n\n\n`setindex!(st::SymmetricTensor, x::Float, mulind::Int...)` changes all symmetric tensor's elements indexed by `mulind` to `x`.\n\n```julia\njulia\u003e st[1,2] = 10.\n\njulia\u003e convert(Array, st)\n2×2 Array{Float64,2}:\n  0.533183  10.0      \n 10.0        0.0176868\n\n```\n\n## Auxiliary function\n\n```julia\njulia\u003e unfold(data::Array{T,N}, mode::Int)\n```\nunfolds `data` in a given mode\n\n```julia\njulia\u003e a = reshape(collect(1.:8.), (2,2,2))\n2×2×2 Array{Float64,3}:\n[:, :, 1] =\n 1.0  3.0\n 2.0  4.0\n\n[:, :, 2] =\n 5.0  7.0\n 6.0  8.0\n\njulia\u003e unfold(a, 1)\n2×4 Array{Float64,2}:\n 1.0  3.0  5.0  7.0\n 2.0  4.0  6.0  8.0\n\njulia\u003e unfold(a, 2)\n2×4 Array{Float64,2}:\n 1.0  2.0  5.0  6.0\n 3.0  4.0  7.0  8.0\n\njulia\u003e unfold(a, 3)\n2×4 Array{Float64,2}:\n 1.0  2.0  3.0  4.0\n 5.0  6.0  7.0  8.0\n```\n\n## Block structure\n\nThe block usage is motivated by the paper M. D. Schatz, T. M. Low, R. A. van de Geijn, and T. G. Kolda, \"Exploiting symmetry in tensors for high performance: Multiplication with symmetric tensors\", SIAM Journal on Scientific Computing, 36 (2014), pp. C453–C479 https://doi.org/10.1137/130907215. There only the meaningful part of the symmetric tensor is stored in blocks to decrease the memory and computational overhead. \n\nFor application of this representation to compute cumulants, see: K. Domino, P. Gawron, Ł. Pawela \"Efficient Computation of Higher-Order Cumulant Tensors\", \nSIAM Journal on Scientific Computing, 40 (2018) https://doi.org/10.1137/17M1149365. The selection of the optimal block size is not straight forward, however in most cases concerning cumulants one can use `2` or `3`.\n\n\n\nThis project was partially financed by the National Science Centre, Poland – project number 2014/15/B/ST6/05204.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiitis%2Fsymmetrictensors.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiitis%2Fsymmetrictensors.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiitis%2Fsymmetrictensors.jl/lists"}