根据是否存在可选关键字参数设置函数输出类型

时间:2014-07-30 20:07:34

标签: julia

我需要制作直方图,每个数据点都带有统计权重。标准hist功能无法处理此问题。我当然可以导入numpy.histogram function,它可以很好地处理加权数据,但我认为学习julia尝试增强hist()函数是一个很好的练习接受权重作为可选(命名)参数。

我首先查看了hist()的julia来源,并且能够略微修改它(如果是业余性的 - 欢迎提出改进建议),让它有点工作:

function sturges(n)  # Sturges' formula
    n==0 && return one(n)
    iceil(log2(n))+1
end

function weightedhist!{HT}(h::AbstractArray{HT}, v::AbstractVector, edg::AbstractVector; init::Bool=true, weights::AbstractVector = ones(HT,length(v)))
    n = length(edg) - 1
    length(weights) == length(v) || error("length(weights) must equal length(v)")
    length(h) == n || error("length(h) must equal length(edg) - 1.")
    if init
        fill!(h, zero(HT))
    end
    for j=1:length(v)
        i = searchsortedfirst(edg, v[j])-1
        if 1 <= i <= n
            h[i] += weights[j]
        end
    end
    edg, h
end

weightedhist(v::AbstractVector, edg::AbstractVector; weights::AbstractVector = ones(Int,length(v))) = weightedhist!(Array(Float64, length(edg)-1), v, edg; weights=weights)
weightedhist(v::AbstractVector, n::Integer; weights::AbstractVector = ones(Int,length(v))) = weightedhist(v, histrange(v,n); weights=weights)
weightedhist(v::AbstractVector; weights::AbstractVector = ones(Int,length(v))) = weightedhist(v, sturges(length(v)); weights=weights)

如果我使用

生成一些随机数据
v = randn(10^5);
w = rand(length(v));
edges = floor(minimum(v)):0.1:ceil(maximum(v));

然后weightedhist(v, edges; weights=w)同意numpy.histogram(v, edges, weights=w)。如果我省略了权重的可选关键字参数,则weightedhist(v, edges)同意内置hist(v, edges),而weightedhist(v)同意内置hist(v)除外< / strong>因为当没有提供权重时,我的函数输出浮动而不是整数。

我不明白为什么会出现这种情况(是否会被创建为一个浮点数组?提升?),我希望我的函数能够像内置的那样依赖于内置的行为当没有提供重量时可能。

有人可以建议为什么我的函数输出浮点数,以及如何在没有提供权重的情况下将该行为更改为输出整数?我想在没有先创建h数组然后将其从一种类型转换为另一种类型的情况下这样做,因为我希望代码尽可能快。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,请致电

weightedhist(v, edges)

您正在使用底部三个“额外”定义中的第一个。

这叫

weightedhist!(Array(Float64, length(edg)-1), v, edg; weights=weights)

因此,在您的“主要”weightedhist!中,HT参数化将为Float64,因此hfillHT = = Float64,因此Float64输出。我相信,将它改为Array(eltype(weights), length(edg)-1)就足够了。