我想知道Julia中是否有命令或包允许我们直接提取矩阵的下三角部分,不包括对角线。我可以为此调用R命令(比如gdata包的lowerTriangle),但是我想知道Julia是否有类似的东西。例如,假设我有矩阵
1.0 0.751 0.734
0.751 1.0 0.948
0.734 0.948 1.0
我不想创建像
这样的下三角矩阵NA NA NA
0.751 NA NA
0.734 0.948 NA
但是将矩阵的下半部分提取为数组:0.751 0.734 0.948
答案 0 :(得分:5)
如果你可以创建一个下三角矩阵作为中间步骤,你可以使用逻辑索引和"dependencies": {
"axios": "^0.16.2",
"babel-polyfill": "^6.26.0",
"babel-runtime": "^6.23.0",
"bluebird": "^3.5.1",
"dotenv": "^4.0.0",
"mongodb": "^2.2.31"
}
和一个额外的参数来获得你需要的东西。
tril!
julia> M = [1.0 0.751 0.734
0.751 1.0 0.948
0.734 0.948 1.0];
julia> v = M[tril!(trues(size(M)), -1)]
3-element Array{Float64, 1}:
0.751
0.734
0.948
调用返回一个M形状的数组,其中填充了布尔trues
值。 true
然后将其修剪为我们想要的矩阵部分。 tril的第二个参数!告诉它从哪个超对角线开始,我们在这里使用它来避免前导对角线中的值。
我们使用它的结果来索引到M,并返回一个具有所需值的数组。
答案 1 :(得分:2)
julia> [M[m, n] for m in 2:size(M, 1) for n in 1:m-1]
3-element Array{Float64,1}:
0.751
0.734
0.948
但它比
lower_triangular_1(M) = [M[m, n] for m in 2:size(M, 1) for n in 1:m-1]
lower_triangular_2(M) = [M[m, n] for n in 1:size(M, 2) for m in n+1:size(M, 1)]
lower_triangular_3(M) = M[tril!(trues(size(M)), -1)]
using BenchmarkTools
using LinearAlgebra # avoid warning in 0.7
M=rand(100, 100)
使用Julia Version 0.7.0-alpha.0
进行测试:
julia> @btime lower_triangular_1(M);
73.179 μs (10115 allocations: 444.34 KiB)
julia> @btime lower_triangular_2(M);
71.157 μs (10117 allocations: 444.41 KiB)
julia> @btime lower_triangular_3(M);
16.325 μs (6 allocations: 40.19 KiB)
不优雅,但更快(使用@views
):
function lower_triangular_4(M)
# works only for square matrices
res = similar(M, ((size(M, 1)-1) * size(M, 2)) ÷ 2)
start_idx = 1
for n = 1:size(M, 2)-1
@views column = M[n+1:end, n]
last_idx = start_idx -1 + length(column)
@views res[start_idx:last_idx] = column[:]
start_idx = last_idx + 1
end
end
julia> @btime lower_triangular_4(M);
4.272 μs (101 allocations: 44.95 KiB)