Julia 无法理解累积量的简单用法。jl

Julia 无法理解累积量的简单用法。jl,julia,Julia,我一辈子都搞不懂如何使用Cumulants.jl从一些数据中获取矩或累积量。我发现这些文件()完全让我不知所措 假设我有一些数据的向量,例如: using Distributions d = rand(Exponential(1), 1000) 据我所知,文档表明,累积量(d,3)应该返回前三个累积量。函数的定义如下: cumulants(data::Matrix{T}, m::Int = 4, b::Int = 2) where T<: AbstractFloat 但我得到: jul

我一辈子都搞不懂如何使用Cumulants.jl从一些数据中获取矩或累积量。我发现这些文件()完全让我不知所措

假设我有一些数据的向量,例如:

using Distributions
d = rand(Exponential(1), 1000)
据我所知,文档表明,
累积量(d,3)
应该返回前三个累积量。函数的定义如下:

cumulants(data::Matrix{T}, m::Int = 4, b::Int = 2) where T<: AbstractFloat
但我得到:

julia> cumulants(dm,3)
ERROR: DimensionMismatch("bad block size 2 > 1")
我的问题很简单:如何使用Cumulants.jl从一些模拟数据中获得第一个
m
累积量和第一个
m

谢谢

编辑:在上面的示例中,注释中建议的
c=累积量(dm,3,1)
将给出
c

3-element Array{SymmetricTensors.SymmetricTensor{Float64,N} where N,1}:
 SymmetricTensors.SymmetricTensor{Float64,1}(Union{Nothing, Array{Float64,1}}[[1.0122452678071678]], 1, 1, 1, true)
 SymmetricTensors.SymmetricTensor{Float64,2}(Union{Nothing, Array{Float64,2}}[[1.0336298356976195]], 1, 1, 1, true)
 SymmetricTensors.SymmetricTensor{Float64,3}(Union{Nothing, Array{Float64,3}}[[2.5438037582591146]], 1, 1, 1, true)
我发现我可以通过以下方式访问第一、第二和第三累积量:

c[1][1]
c[2][1,1]
c[3][1,1,1]

我基本上是通过猜测得出的。我不知道为什么会有这种古怪的输出格式。我仍然不知道如何轻松获得第一个
m
累积量作为向量。

如我在评论中所述,如果你有单变量问题,你应该使用
累积量(dm,3,1)
,因为累积量是使用张量计算的,张量保存在块结构中,其中块的大小为bxb,即函数调用中的第三个参数。但是,如果只有一列,则张量的大小将为1,因此将其保存在2x2块中没有意义

要访问数组形式的累积量,必须首先转换它们。这是通过数组(累积量(data,nc,b)[c])完成的,其中nc是要计算的累积量的数量,b是块大小(用于有效存储张量),c是所需的累积量。 总结:

using Cumulants

# univariate data

unidata = rand(1000,1)
uc = cumulants(unidata, 3, 1)
Array(uc[1])
#1-element Array{Float64,1}:
# 0.48772026299259374
Array(uc[2])
#1×1 Array{Float64,2}:
# 0.0811428357438324
Array(uc[3])
#[:, :, 1] =
# 0.0008653019738796724

# multivariate data

multidata = rand(1000,3)
mc = cumulants(multidata, 3, 2)
Array(mc[1])
#3-element Array{Float64,1}:
# 0.5024511157116442
# 0.4904838734508787
# 0.48286680648519215
Array(mc[2])
#3×3 Array{Float64,2}:
#  0.0834021   -0.00368562  -0.00151614
# -0.00368562   0.0835084    0.00233202
# -0.00151614   0.00233202   0.0808521
Array(mc[3])
# [:, :, 1] =
#  -0.000506926  -0.000763061  -0.00183751
#  -0.000763061  -0.00104804   -0.00117227
#  -0.00183751   -0.00117227    0.00112968
# 
# [:, :, 2] =
#  -0.000763061  -0.00104804   -0.00117227
#  -0.00104804    0.000889305  -0.00116559
#  -0.00117227   -0.00116559   -0.000106866
# 
# [:, :, 3] =
#  -0.00183751  -0.00117227    0.00112968
#  -0.00117227  -0.00116559   -0.000106866
#   0.00112968  -0.000106866   0.00131965
块的最佳大小可以在他们的软件论文()中找到,他们在论文中写道(关于正确的latex格式,请查看论文):

5.2.1块的最佳大小。 存储d阶和n阶超对称张量所需的系数数等于(d+n)−1比n)。不考虑超对称性的张量存储需要n^d系数。[49]中介绍的块结构使用了超过最小内存量的内存,但允许更容易地进一步处理超对称张量。如果我们将超对称张量存储在块结构中,则会出现块大小参数b。在我们的实现中,为了在块结构中存储超对称张量,假设n | b,一个指向块的(n/b)d指针数组和一个包含指针指向有效块时信息的相同大小标志数组。回想一下,对角块包含冗余信息。因此,一方面,b的值越小,块结构对角线上的冗余元素就越少。另一方面,b的值越大,块的数量越小,块的操作开销越小,指向空块的指针数量越少。有关内存使用的详细讨论,请参见[49]。图2分析了参数b对某些参数累积量计算时间的影响。在几乎所有的测试用例中,我们获得了b=2的最短计算时间,该值将设置为默认值,并在所有效率测试中使用。注意,对于b=1,我们失去了所有的内存节省


使用Oskar的有用答案,我想我应该提供我的包装函数,在给定1D数据数组输入的情况下,实现返回第一个
m
累积量向量的目标

using Cumulants
function mycumulants(d, m) # given a 1D array of data d, return a vector of the first m cumulants
    res = zeros(m)
    dm = reshape(d, length(d), 1) # Convert 1D array to 2D
    c = cumulants(dm, m, 1) # Need the 1 (block size) or else it errors
    for i in 1:m
        res[i] = Array(c[i])[1]
    end
    return(res)
end
但事实证明,与直接计算原始矩并通过例如
k[5]=u[5]-5*u[4]*u[1]-10*u[3]*u[2]+20*u[3]*u[1]^2+30*u[2]^2*u[1]-60*u[2]*u[1]^3+24*u[1]^5
将它们转换为累积量相比,这实在太慢了,所以我想我不会使用累积量。毕竟,出于我的目的,目前只涉及单变量数据

从一些模拟数据计算前六个累积量的时差示例:

----Data set 2----

Direct calculation:
  1.997 ms (14 allocations: 469.47 KiB)

Cumulants.jl:
  152.798 ms (318435 allocations: 17.59 MiB)

那么累积量(dm,3,1)呢??啊,谢谢……你明白第三个参数在做什么吗?文档中说“默认值为2的参数b是一个可选的Int,它决定了SymmetricTensors类型中块的大小”,这对我来说毫无意义。另外,你知道如何从输出中提取作为向量的累积量吗?就像严肃地说这是什么意思一样,我只想要累积量(我可以看到它们在那里):
3元素数组{SymmetricTensor.SymmetricTensor{Float64,N},其中N,1}:SymmetricTensor.SymmetricTensor{Float64,1}(Union{Nothing,Array{Float64,1}[对称传感器{Float64,2}(联合{Nothing,Array{Float64,2}[[1.0336298356976195]],1,1,1,1,真)对称传感器{Float64,3}(联合{Nothing,Array{Float64,2}[[1.0336298356976195]],1,1,1,真)
我提出了一个问题,要求他们改进关于块大小的文档。
数组(uc[1])
返回一个1元素的一维数组,而
数组(uc[3])
返回一个1元素的3-D数组。然后我需要从每个数组中选取第一个元素。因此,要将第三个累积量作为一个数字,例如,我需要执行
数组(uc[3])[1]
。这对我来说真是太疯狂了,但可能我就是不明白为什么会返回这些不同的结构。更重要的是,我非常感谢您的帮助,谢谢!我认为他们这样做的原因是他们计划了用于多变量数据的包。因此,为thir使用3D阵列是有意义的d累积量。在单变量数据中,它没有,而且用张量来计算它也没有什么意义,我想。对单变量数据来说,它也非常慢,见下文
----Data set 2----

Direct calculation:
  1.997 ms (14 allocations: 469.47 KiB)

Cumulants.jl:
  152.798 ms (318435 allocations: 17.59 MiB)