在 Julia 中接受所有数字矩阵向量作为函数参数

Accepting all vectors of matrices of numbers as a function argument in Julia

我正在尝试编写一个函数,它接受一个矩阵向量并递归地计算它们的乘积。函数本身是这样的:

using LinearAlgebra: I

"""
Recursively calculates the product of the matrices in a given vector `V`.
"""
function ∏_(V)
    if length(V) == 1
        return V[1]
    elseif length(V) == 0
        UniformScaling(1)
    else
        V[1] * ∏_(V[2:end])
    end
end

一切都很好,但我想将输入的类型限制为

V::Vector{Matrix{Number}} ,

其中 Number 可以是任何字段元素(整数、有理数或复数)。我如何使用 Julia 的类型注释来实现这一点?我知道子类型运算符 <:,但写作

V::Vector{Matrix{<:Number}}

简单地产生错误

ERROR: LoadError: MethodError: no method matching ∏_(::Array{Array{Rational{Int64},2},1})
Closest candidates are:
    ∏_(::Array{Array{var"#s1",2} where var"#s1"<:Number,1})

当给函数一个有理整数矩阵数组时。我该如何解决这个问题?

您需要指定V::Vector{<:Matrix{<:Number}}

但是,您可以进一步扩展它以允许更多用途,例如

V::AbstractVector{<:AbstractMatrix{<:Number}}
V::AbstractVector{<:AbstractMatrix}
V::AbstractVector
V::Any

它可能不会伤害任何人,并且可能允许您现在甚至无法想象的未来用途

一般来说,在 Julia 中过度限制输入类型被认为是一种糟糕的形式。尽量让你的类型签名尽可能宽松,如果你不需要进行分派(为不同的输入选择不同的实现),你应该考虑根本不使用类型。

在这种情况下,我可能只使用 V::AbstractVector 并让元素为“支持乘法的任何类型”,恕我直言,甚至没有理由将其限制为 Numbers。

此外,在这种情况下,您可以只使用 prod,这正是您想要的:

 ∏_(V) = prod(V)

顺便说一句:最好写成 ILinearAlgebra.I,而不是 UniformScaling(1)1 参数是一个 Int64,如果它在较低整数的矩阵上运行,如 Int32.

,则可能导致类型提升