{"id":20669477,"url":"https://github.com/iitis/cumulantsupdates.jl","last_synced_at":"2025-12-24T01:32:09.221Z","repository":{"id":51730767,"uuid":"103524792","full_name":"iitis/CumulantsUpdates.jl","owner":"iitis","description":"Updates of high order cumulant tensors","archived":false,"fork":false,"pushed_at":"2023-05-17T10:53:50.000Z","size":192,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-16T21:17:03.007Z","etag":null,"topics":["cumulants"],"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}},"created_at":"2017-09-14T11:34:53.000Z","updated_at":"2022-01-27T14:03:21.000Z","dependencies_parsed_at":"2022-08-03T06:15:17.679Z","dependency_job_id":null,"html_url":"https://github.com/iitis/CumulantsUpdates.jl","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FCumulantsUpdates.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FCumulantsUpdates.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FCumulantsUpdates.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iitis%2FCumulantsUpdates.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iitis","download_url":"https://codeload.github.com/iitis/CumulantsUpdates.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242884504,"owners_count":20201126,"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":["cumulants"],"created_at":"2024-11-16T20:14:29.566Z","updated_at":"2025-12-24T01:32:09.134Z","avatar_url":"https://github.com/iitis.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Coverage Status](https://coveralls.io/repos/github/iitis/CumulantsUpdates.jl/badge.svg?branch=master)](https://coveralls.io/github/iitis/CumulantsUpdates.jl?branch=master)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7034228.svg)](https://doi.org/10.5281/zenodo.7034228)\n\n# CumulantsUpdates.jl\n\nUpdates following statistics of `n`-variate data\n* `d`'th moment tensor,\n* an array of moment tensors of order `1,2,...,d`.\n\nGiven `t` realisations of `n`-variate data: `X ∈ ℜᵗˣⁿ`, and the update `X + ∈ ℜᵘˣⁿ`\nreturns array of updated cumulant tensors of order `1,2,...,d`.\n\nTo store symmetric tensors uses a `SymmetricTensors` type, requires [SymmetricTensors.jl](https://github.com/ZKSI/SymmetricTensors.jl). To convert to array, run:\n\n```julia\njulia\u003e Array(st::SymmetricTensors{T, d})\n```\nto convert back, run:\n\n```julia\njulia\u003e  SymmetricTensor(a::Array{T,d})\n```\nRequires [Cumulants.jl](https://github.com/ZKSI/Cumulants.jl).\n\nAs of 01/01/2017 [kdomino](https://github.com/kdomino) is the lead maintainer of this package.\n\n## Installation\n\nWithin Julia, run\n\n```julia\npkg\u003e add CumulantsUpdates\n```\n\nto install the files. Julia 1.0 or later is required.\n\n## Parallel computation\n\nFor parallel computation just run\n```julia\njulia\u003e addprocs(n)\njulia\u003e @everywhere using CumulantsUpdates\n```\n\n## Functions\n\n### Data update\n\nTo update data `X ∈ ℜᵗˣⁿ` by the update `X+ ∈ ℜᵘˣⁿ` in the observation\nwindow of size `t` and get `ℜᵗˣⁿ ∋ X' = vcat(X,X+)[1+u:end, :]` run:\n\n```julia\njulia\u003e dataupdat(X::Matrix{T}, Xplus::Matrix{T}) where T\u003c:AbstractFloat\n```\nthe condition `u \u003c t` must be fulfilled.\n\n```julia\njulia\u003e a = ones(4,4)\n4×4 Array{Float64,2}:\n 1.0  1.0  1.0  1.0\n 1.0  1.0  1.0  1.0\n 1.0  1.0  1.0  1.0\n 1.0  1.0  1.0  1.0\n\njulia\u003e b = zeros(2,4)\n2×4 Array{Float64,2}:\n 0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0\n\njulia\u003e dataupdat(a,b)\n4×4 Array{Float64,2}:\n 1.0  1.0  1.0  1.0\n 1.0  1.0  1.0  1.0\n 0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0\n```\n\n### Moment update\n\nTo update the moment tensor `M::SymmetricTensor{T, d}` for  data `X ∈ ℜᵗˣⁿ`, given the update `X+ ∈ ℜᵘˣⁿ` where `u \u003c t` run\n\n```julia\njulia\u003e momentupdat(M::SymmetricTensor{T, d}, X::Matrix{T}, Xplus::Matrix{T}) where {T\u003c:AbstractFloat, d}\n```\n\nReturns a `SymmetricTensor{T, d}` of the moment tensor of updated multivariate data:\n`ℜᵗˣⁿ ∈ X' = dataupdat(X,X+)`, i.e.: `M = moment(X, d)`, `momentupdat(M, X, X+) = moment(X', d)`. If `u ≪ t` `momentupdat()` is much faster than a recalculation.\n\n```julia\njulia\u003e x = ones(6, 2);\n\njulia\u003e SymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[1.0 1.0; 1.0 1.0]\n\n[1.0 1.0; 1.0 1.0]], 2, 1, 2, true)\n\n\njulia\u003e y = 2*ones(2,2);\n\njulia\u003e momentupdat(m, x, y)\nSymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[3.33333 3.33333; 3.33333 3.33333]\n\n[3.33333 3.33333; 3.33333 3.33333]], 2, 1, 2, true)\n\n```\n\nFunction `momentarray(X, d)` can be used to compute an array of moments of order `1, ..., d`\nof data `X ∈ ℜᵗˣⁿ`\n\n```julia\njulia\u003e momentarray(X::Matrix{T}, d::Int, b::Int) where {T\u003c:AbstractFloat, d}\n```\n`b` - is a `SymmetricTensor` parameter, a block size.\n\nOne can update an array of moments by calling:\n\n```julia\njulia\u003e momentupdat(M::Array{SymmetricTensor{T, d}}, X::Matrix{T}, Xplus::Matrix{T}) where {T\u003c:AbstractFloat, d}\n```\n\nReturns an `Array{SymmetricTensor{T, d}}` of moment tensors of order `1, ..., d` of updated multivariate data: `ℜᵗˣⁿ ∋ X' = dataupdat(X,X+)`, i.e. `Mₐᵣ = momentarray(X, d)`, `momentupdat(Mₐᵣ, X, X+) = momentarray(X', d)`.\n\n### Cumulants update\n\nPresented functions are design for sequent update of multivariate cumulant tensors.\nHence it can be applied in a data streaming scheme. Suppose one has data `X ∈ ℜᵗˣⁿ`\nand subsequent coming updates `X+ ∈ ℜᵘˣⁿ` such that `u ≪ t`. Suppose one want to compute cumulant tensors in an observation window of size `t` each time the update comes.\nTo store data amd moments we use the following structure `mutable struct DataMoments{T \u003c: AbstractFloat}`\nwith following fields: `X` - data, `d` - maximal order of a moment series, `b` - a block size, `M` - moment series. To initialise, we can use the following constructor:\n\n```julia\njulia\u003e DataMoments(X::Matrix{T}, d::Int, b::Int) where T \u003c: AbstractFloat\n```\nhere an array of moments will be computed. To update a DataMoments structure and compute updated cumulants run:\n\n```julia\n\njulia\u003e cumulantsupdate!(dm::DataMoments{T}, Xplus::Matrix{T}) where T \u003c: AbstractFloat\n\n```\nThe function updates a DataMoment structure and returns a series of cumulants of order `1, ..., dm.d` for updated data. See:\n\n```julia\n\njulia\u003e x = ones(10,2);\n\njulia\u003e s = DataMoments(x, 4, 2);\n\njulia\u003e y = zeros(4,2);\n\njulia\u003e cumulantsupdate!(s,y)[4]\nSymmetricTensor{Float64,4}(Union{Nothing, Array{Float64,4}}[[-0.1056 -0.1056; -0.1056 -0.1056]\n\n[-0.1056 -0.1056; -0.1056 -0.1056]\n\n[-0.1056 -0.1056; -0.1056 -0.1056]\n\n[-0.1056 -0.1056; -0.1056 -0.1056]], 2, 1, 2, true)\n\n```\n\nTo save the DataMoments structure use:\n\n```julia\n\njulia\u003e savedm(dm::DataMoments, dir::String)\n```\n\nTo load it use\n\n```julia\n\njulia\u003e loaddm(dir::String)\n```\nreturns a DataMoments structure stored in a given directory.\n\n\n### The p-norm\n\n```julia\njulia\u003e norm(st::SymmetricTensor{T, d}, p::Union{Float64, Int}) where {T\u003c:AbstractFloat, d}\n```\n\nReturns a `p`-norm of the tensor stored as `SymmetricTensors`, supported for `k ≠ 0`. The output of `norm(st, p) = norn(convert(Array, st),p)`. However\n`norm(st::SymmetricTensor, p)` uses the block structure implemented in `SymmetricTensors`, hence is faster and decreases the computer memory requirement.\n\n```julia\njulia\u003e te = [-0.112639 0.124715 0.124715 0.268717 0.124715 0.268717 0.268717 0.046154];\n\njulia\u003e st = SymmetricTensor(reshape(te, (2,2,2)));\n\njulia\u003e norm(st)\n0.5273572868359742\n\njulia\u003e norm(st, 2.5)\n0.4468668679541424\n\njulia\u003e norm(st, 1)\n1.339089\n```\n### Convert cumulants to moments and moments to cumulants\n\nGiven `M` a vector of moments of order `1, ..., d` to change it to a vector\nof cumulants of order `1, ..., d` using\n\n```julia\njulia\u003e function moms2cums!(M::Vector{SymmetricTensor{T}}) where T \u003c: AbstractFloat\n```\nOne can convert a vector of cumulants `c` to a vector of moments by running\n\n```julia\njulia\u003e function cums2moms(c::Vector{SymmetricTensor{T}}) where T \u003c: AbstractFloat\n```\n\n```julia\n\njulia\u003e m = momentarray(ones(20,3), 3, 2)\n3-element Array{SymmetricTensor{Float64,N} where N,1}:\n SymmetricTensor{Float64,1}(Union{Nothing, Array{Float64,1}}[[1.0, 1.0], [1.0]], 2, 2, 3, false)                                                                                                                              \n SymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[1.0 1.0; 1.0 1.0] [1.0; 1.0]; nothing [1.0]], 2, 2, 3, false)                                                                                                   \n SymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[1.0 1.0; 1.0 1.0]\n[1.0 1.0; 1.0 1.0] nothing; nothing nothing]\nUnion{Nothing, Array{Float64,3}}[[1.0 1.0; 1.0 1.0] [1.0; 1.0]; nothing [1.0]], 2, 2, 3, false)\n\n\njulia\u003e moms2cums!(m)\n\njulia\u003e m\n3-element Array{SymmetricTensor{Float64,N} where N,1}:\n SymmetricTensor{Float64,1}(Union{Nothing, Array{Float64,1}}[[1.0, 1.0], [1.0]], 2, 2, 3, false)                                                                                                                          \n SymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[0.0 0.0; 0.0 0.0] [0.0; 0.0]; #undef [0.0]], 2, 2, 3, false)                                                                                                \n SymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[0.0 0.0; 0.0 0.0]\n[0.0 0.0; 0.0 0.0] #undef; #undef #undef]\nUnion{Nothing, Array{Float64,3}}[[0.0 0.0; 0.0 0.0] [0.0; 0.0]; #undef [0.0]], 2, 2, 3, false)\n\n\njulia\u003e cums2moms(m)\n3-element Array{SymmetricTensor{Float64,N} where N,1}:\n SymmetricTensor{Float64,1}(Union{Nothing, Array{Float64,1}}[[1.0, 1.0], [1.0]], 2, 2, 3, false)                                                                                                                          \n SymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[1.0 1.0; 1.0 1.0] [1.0; 1.0]; #undef [1.0]], 2, 2, 3, false)                                                                                                \n SymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[1.0 1.0; 1.0 1.0]\n[1.0 1.0; 1.0 1.0] #undef; #undef #undef]\nUnion{Nothing, Array{Float64,3}}[[1.0 1.0; 1.0 1.0] [1.0; 1.0]; #undef [1.0]], 2, 2, 3, false)\n\n\n\n```\n# Performance tests\n\nTo analyse the computational time of cumulants updates vs `Cumulants.jl` recalculation, we supply the executable script `comptimes.jl`. The script saves computational times to the `res/*.jld` file. The scripts accept following parameters:\n* `-d (Int)`: cumulant's maximum order, by default `d = 4`,\n* `-n (vararg Int)`: numbers of marginal variables, by default `n = 40`,\n* `-t (Int)`: number of realisations of random variable, by default `t = 500000`,\n* `-u (vararg Int)`: number of realisations of update, by default `u = 10000, 15000, 20000`,\n* `-b (Int)`: blocks size, by default `b = 4`,\n* `-p (Int)`: numbers of processes, by default `p = 3`.\n\nTo analyse the computational time of cumulants updates for different block sizes `1 \u003c b ≤ Int(√n)+2`, we supply the executable script `comptimesblocks.jl`.\nThe script saves computational times to the `res/*.jld` file. The scripts accept following parameters:\n* `-d (Int)`: cumulant's order, by default `d = 4`,\n* `-n (Int)`: numbers of marginal variables, by default `n = 48`,\n* `-u (vararg Int)`: number of realisations of the update, by default `u = 10000, 20000`.\n* `-p (Int)`: numbers of processes, by default `p = 3`.\n\nTo analyse the computational time of cumulants updates for different number of workers, we supply the executable script `comptimesprocs.jl`.\nThe script saves computational times to the `res/*.jld` file. The scripts accept following parameters:\n* `-d (Int)`: cumulant's order, by default `d = 4`,\n* `-n (Int)`: numbers of marginal variables, by default `n = 48`,\n* `-u (vararg Int)`: number of realisations of the update, by default `u = 10000, 20000`,\n* `-b (Int)`: blocks size, by default `b = 4`,\n* `-p (Int)`: maximal numbers of processes, by default `p = 6`.\n\nTo plot computational times run executable `res/plotcomptimes.jl` on chosen `*.jld` file.\n\n\n# Citing this work\n\nKrzysztof Domino, Piotr Gawron, *An algorithm for arbitrary–order cumulant tensor calculation in a sliding window of data streams*,\nInternational Journal of Applied Mathematics and Computer Science, vol. 29, issue 1, pp. 206, 2019  (https://doi.org/10.2478/amcs-2019-0015 )\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%2Fcumulantsupdates.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiitis%2Fcumulantsupdates.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiitis%2Fcumulantsupdates.jl/lists"}