cov(A,mean = 0)给出InexactError

时间:2014-07-31 06:19:14

标签: statistics julia

设置InexactError()时,我在计算矩阵中行的协方差时得到mean=0

julia> A = [1 -1 -1; -1 1 1; -1 1 -1; 1 -1 -1; 1 -1 1]
5x3 Array{Int64,2}:
  1  -1  -1
 -1   1   1
 -1   1  -1
  1  -1  -1
  1  -1   1

julia> cov(A) # Works
3x3 Array{Float64,2}:
  1.2  -1.2  -0.2
 -1.2   1.2   0.2
 -0.2   0.2   1.2

julia> cov(A, mean=[0. 0. 0.]) # Works
3x3 Array{Float64,2}:
  1.25  -1.25  -0.25
 -1.25   1.25   0.25
 -0.25   0.25   1.25

julia> cov(A, mean=0) # Expecting same output as above
ERROR: InexactError()
 in generic_scale! at linalg/generic.jl:18
 in covzm at statistics.jl:253
 in cov at statistics.jl:286

Docs for Base.cov说:

  

表示:允许用户提供已知的平均值。默认情况下,它设置为nothing,表示均值未知,函数将计算均值。 用户可以使用mean = 0表示输入数据居中,因此无需减去平均值

Julia来源(statistics.jl, line 286)清楚地测试是否已通过mean=0

function cov(x::AbstractMatrix; vardim::Int=1, corrected::Bool=true, mean=nothing)
    mean == 0 ? covzm(x; vardim=vardim, corrected=corrected) :
    mean == nothing ? covm(x, _vmean(x, vardim); vardim=vardim, corrected=corrected) :
    isa(mean, AbstractArray) ? covm(x, mean; vardim=vardim, corrected=corrected) :
    error("Invalid value of mean.")
end

我做错了什么还是这个错误?

2 个答案:

答案 0 :(得分:2)

我认为这应该被视为一个错误。在完成代码之后,有问题的错误发生在generic.jl的第18行,特别是以下函数。

function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number)
    length(C) == length(X) || error("C must be the same length as X")
    for i = 1:length(X)
        @inbounds C[i] = X[i]*s
    end
    C
end

其中3变量形式由2变量形式调用,如下所示:

generic_scale!(X::AbstractArray, s::Number) = generic_scale!(X, X, s)

此时,from looking at the source,s的值为0.25,X将具有以下结果

x = unscaled_covzm(A, 1)
3x3 Array{Int64,2}:
  5  -5  -1
 -5   5   1
 -1   1   5

将上述定义剪切并粘贴到REPL中,可以直接测试generic_scale

julia> generic_scale!(x,x,0.25)
ERROR: InexactError()
 in generic_scale! at none:4

原因是X是Int64的矩阵,导致转换抛出不准确的错误,因为1.25不能用int表示。如果X是Float64,则没有错误:

julia> x = unscaled_covzm(A, 1)*1.0
3x3 Array{Float64,2}:
  5.0  -5.0  -1.0
 -5.0   5.0   1.0
 -1.0   1.0   5.0

julia> generic_scale!(x,x,0.25)
3x3 Array{Float64,2}:
  1.25  -1.25  -0.25
 -1.25   1.25   0.25
 -0.25   0.25   1.25

因此,如果您从示例中定义了一个Float64版本的A

julia> B=A*1.0
5x3 Array{Float64,2}:
  1.0  -1.0  -1.0
 -1.0   1.0   1.0
 -1.0   1.0  -1.0
  1.0  -1.0  -1.0
  1.0  -1.0   1.0

julia> cov(B,mean=0)
3x3 Array{Float64,2}:
  1.25  -1.25  -0.25
 -1.25   1.25   0.25
 -0.25   0.25   1.25

答案 1 :(得分:1)

也许它不是正确的答案。我只是想说,如果你替换'= mean = 0'用&= 39; mean = [0。]'在你的行中,Julia得到以下答案。 :)

julia> cov(A,mean=[0.])
3x3 Array{Float64,2}:
  1.25  -1.25  -0.25
 -1.25   1.25   0.25
 -0.25   0.25   1.25