提取矩阵的下三角部分

时间:2018-06-01 22:37:29

标签: matrix julia

我想知道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

2 个答案:

答案 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)

使用comprehensions

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)