检查数组 Julia 中单调性的有效方法?

Efficient method for checking monotonicity in array Julia?

试图想出一种快速的方法来确保 a 在 Julia 中是单调的。

我一直使用的缓慢(且明显)的方法是这样的:

function check_monotonicity(
    timeseries::Array,
    column::Int
)
    current = timeseries[1,column]
    for row in 1:size(timeseries, 1)
        if timeseries[row,column] > current 
            return false
        end 
        current = copy(timeseries[row,column])
    end 
    return true
end

所以它的工作原理是这样的:

julia> using Distributions

julia>mono_matrix = hcat(collect(0:0.1:10), rand(Uniform(0.4,0.6),101),reverse(collect(0.0:0.1:10.0)))
101×3 Matrix{Float64}:
  0.0  0.574138  10.0
  0.1  0.490671   9.9
  0.2  0.457519   9.8
  0.3  0.567687   9.7
  ⋮              
  9.8  0.513691   0.2
  9.9  0.589585   0.1
 10.0  0.405018   0.0
julia> check_monotonicity(mono_matrix, 2)
false

然后是相反的例子:

julia> check_monotonicity(mono_matrix, 3)
true

有谁知道对长时间序列执行此操作的更有效方法吗?

在数学中,通常我们将一个级数定义为单调的,如果它是 non-decreasing 或 non-increasing。如果这是你想要的,那么做:

issorted(view(mono_matrix, :, 2), rev=true)

检查是否为non-increasing,并且:

issorted(view(mono_matrix, :, 2))

检查它是否是 non-decreasing。

如果你想要递减支票:

issorted(view(mono_matrix, :, 3), rev=true, lt = <=)

用于减少,但将 0.0-0.0 视为相等或

issorted(view(mono_matrix, :, 3), lt = <=)

用于增加,但将 0.0-0.0 视为相等。

如果要区分0.0-0.0则分别做:

issorted(view(mono_matrix, :, 3), rev=true, lt = (x, y) -> isequal(x, y) || isless(x, y))
issorted(view(mono_matrix, :, 3), lt = (x, y) -> isequal(x, y) || isless(x, y))

你的实现肯定不慢!它几乎是最佳速度。你绝对应该去掉 copy。虽然当矩阵元素只是普通数据时它不会受到伤害,但在其他情况下可能会很糟糕,例如 BigInt

这与您最初的成果很接近,但在索引和数组类型方面也更稳健:

function ismonotonic(A::AbstractMatrix, column::Int, cmp = <)
    current = A[begin, column] # begin instead of 1
    for i in axes(A, 1)[2:end] # skip the first element
        newval = A[i, column] # don't use copy here
        cmp(newval, current) && return false
        current = newval
    end
    return true
end

另一个提示:您不需要使用 collect。事实上,您几乎 永远不会 使用 collect。改为这样做(我删除了 Uniform,因为我没有 Distributions.jl):

mono_matrix = hcat(0:0.1:10, rand(101), reverse(0:0.1:10)) # or 10:-0.1:0

或者这样更好,因为您可以更好地控制范围内的元素数量:

mono_matrix = hcat(range(0, 10, 101), rand(101), range(10, 0, 101))

那么你可以这样使用它:

1.7.2> ismonotonic(mono_matrix, 3)
false

1.7.2> ismonotonic(mono_matrix, 3, >=)
true

1.7.2> ismonotonic(mono_matrix, 1)
true