Julia:Cholesky 分解中的 U 因子不是一个域?

Julia: U factor in Cholesky factorization is not a field?

假设我有以下

> L = [5 1; 1 3]

> chol = LinearAlgebra.cholesky(L)
LinearAlgebra.Cholesky{Float64,Array{Float64,2}}
U factor:
2×2 LinearAlgebra.UpperTriangular{Float64,Array{Float64,2}}:
 2.23607  0.447214
  ⋅       1.67332

我想访问矩阵,更具体地说,对矩阵进行切片并获取第一行、第二行等,这样我就可以像这样访问因子 U

> chol.U
2×2 LinearAlgebra.UpperTriangular{Float64,Array{Float64,2}}:
 2.23607  0.447214
  ⋅       1.67332

我的问题是:.U 到底代表什么?如果我尝试 getfield(chol, :U) 我会得到一个错误,因为没有字段 :U 实际上,fieldnames(LinearAlgebra.Cholesky) returns :factors:uplo:info.

我在这里错过了什么?

在 Julia 1.0 中,点语法 x.s 对于 getproperty(x, :s) 是 shorthand,就像 x[idx] 映射到 getindex(x, idx) 一样。因此,你可以让它以任何你想要的方式运行。只有通用默认值等同于让您访问对象的字段。要查看为 Cholesky 类型的对象调用的特定方法,您可以使用 @which,如下所示:

julia> @which chol.U
getproperty(C::Cholesky, d::Symbol) in LinearAlgebra at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.0\LinearAlgebra\src\cholesky.jl:339

如果您查看 cholesky.jl:339 中的源代码,您会发现以下内容:

function getproperty(C::Cholesky, d::Symbol)
    Cfactors = getfield(C, :factors)
    Cuplo    = getfield(C, :uplo)
    info     = getfield(C, :info)
    if d == :U
        return UpperTriangular(Cuplo === char_uplo(d) ? Cfactors : copy(Cfactors'))
    elseif d == :L
        return LowerTriangular(Cuplo === char_uplo(d) ? Cfactors : copy(Cfactors'))
    elseif d == :UL
        return (Cuplo === 'U' ? UpperTriangular(Cfactors) : LowerTriangular(Cfactors))
    else
        return getfield(C, d)
    end
end

我们看到在 d == :U 的情况下,它没有映射到 getfield(C, d) 之类的东西,而是以某种方式构造了一个 UpperTriangular 矩阵。只有一些通用符号 d 方法映射到 getfield(C, d).

最后,fieldnames 字段的吊坠是 propertynames 属性(您可以在 x.s 中为 s 编写的内容):

julia> propertynames(chol)
(:U, :L, :UL)

julia> fieldnames(typeof(chol))
(:factors, :uplo, :info)

如您所见,字段和属性这两个概念可以是正交的。在这种情况下,没有直接重叠。