覆盖自定义 Julia 结构的反斜杠

Overriding backslash for custom Julia struct

我正在通过扩展 LinearAlgebra 模块中的功能来创建自定义矩阵库。我一直在通过在自定义 MyLinearAlgebra 模块中创建自定义结构来实现这一点,该模块直接导入默认的线性代数结构并覆盖许多常见的 LA 功能。我的问题具体是关于如何覆盖反斜杠函数。这是我的 "MyLinearAlgebra.jl":

module MyLinearAlgebra

import LinearAlgebra
import Base: getindex, setindex!, size

export
# Types
LocalMatrix,
SolutionVector,
# Functions
lp_error!,
lp_norm,
true_size

include("SolutionVector.jl")
include("LocalMatrix.jl")

end

现在只关注 LocalMatrix.jl,我有:

"""
    struct LocalMatrix{T} <: AbstractMatrix{T}
Block diagonal structure for local matrix. `A[:,:,iS,iK]` is a block matrix for
state iS and element iK
"""
struct LocalMatrix{T} <: AbstractMatrix{T}
    data::Array{T,4}
    factorizations::Array{Any,2}

    function LocalMatrix(data::Array{T,4}) where {T}
        new{T}(data,Array{Any}(undef, size(data,3), size(data,4)))
    end
end

# [... a lot of things that are already working including: ldiv!]

"""
    ldiv!(A::LocalMatrix, x::SolutionVector)
In-place linear solve A\x using block-diagonal LU factorizations. Compute this
block-diagonal factorization if not yet computed.
"""
function LinearAlgebra.ldiv!(A::LocalMatrix, x::SolutionVector)
    println("my ldiv! works fine")
    x
end
    
# [ ... and yet this does not work ]
"""
    A::LocalMatrix \ x::SolutionVector
Linear solve A\x using block-diagonal LU factorizations. Compute this
block-diagonal factorization if not yet computed.
"""
function (\)(A::LocalMatrix, x::SolutionVector)
    println("my \ never prints out in any tests")
    (m,n,ns,ne) = size(A.data)
    (nx,nsx,nex) = size(x.data)
    @assert n == nx && ne == nex && m == n
    b = deepcopy(x)
    LinearAlgebra.ldiv!(A, b)
end

在我的测试中,我可以完全按照预期使用 ldiv! 函数,但我不能使用 \ 函数 - 它只是使用其他地方编写的一些标准实现。我相信这大概是因为我的反斜杠函数不符合 LinearAlgebra 反斜杠函数的条件,但我不确定。尝试将函数限定为 LinearAlgebra.(\)(A::LocalMatrix, x::SolutionVector) 失败并出现语法错误 invalid function name。有没有其他方法可以做到这一点,或者我在这里遗漏了一些关于模块的更基本的东西?

\定义在Base中,所以:

julia> "a" \ "b"
ERROR: MethodError: no method matching adjoint(::String)

julia> Base.:\(::String, ::String) = "hello"

julia> "a" \ "b"
"hello"

但是,由于它被导入 LinearAlgebra,因此以下内容也适用于我(我使用的是新会话):

julia> using LinearAlgebra

julia> "a" \ "b"
ERROR: MethodError: no method matching adjoint(::String)

julia> LinearAlgebra.:\(::String, ::String) = "hello"

julia> "a" \ "b"
"hello"

因为 Julia 会向同一个函数(在 Base 中定义)添加一个方法。