假设我有以下
> 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)
返回:factors
、:uplo
和:info
。
我在这里错过了什么?
在Julia 1.0中,点语法x.s
是getproperty(x, :s)
的简写,就像x[idx]
映射到getindex(x, idx)
一样。因此,你可以让它以你想要的任何方式表现。只有通用默认值相当于允许您访问对象的字段。要查看为类型为Cholesky
的对象调用的特定方法,可以按如下方式使用@which
:
julia> @which chol.U
getproperty(C::Cholesky, d::Symbol) in LinearAlgebra at C:cygwinhomeAdministratorbuildbotworkerpackage_win64buildusrsharejuliastdlibv1.0LinearAlgebrasrccholesky.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)
正如您所看到的,字段和属性这两个概念可以是正交的。在这种情况下,没有直接重叠。