Нижняя треугольная матрица в julia

У меня количество столбцов равно количеству строк. А диагональ равна нулю. Как я могу построить эту матрицу?

#mat
#     [,1] [,2] [,3] [,4]
#[1,]   0   NA   NA   NA
#[2,]    1   0   NA   NA
#[3,]    2    4   0   NA
#[4,]    3    5    6   0

Я пробовал это

x=rand(4,4)
4x4 Array{Float64,2}:
 0.60064   0.917443  0.561744   0.135717 
 0.106728  0.72391   0.0894174  0.0656103
 0.410262  0.953857  0.844697   0.0375045
 0.476771  0.778106  0.469514   0.398846 

c=LowerTriangular(x)

4x4 LowerTriangular{Float64,Array{Float64,2}}:
 0.60064   0.0       0.0       0.0     
 0.106728  0.72391   0.0       0.0     
 0.410262  0.953857  0.844697  0.0     
 0.476771  0.778106  0.469514  0.398846

но я ищу что-то вроде этого

c=LowerTriangular(x)
4x4 LowerTriangular{Float64,Array{Float64,2}}:
 0.0   NA      NA       NA    
 0.106728  0.0    NA      NA    
 0.410262  0.953857  0.0 NA     
 0.476771  0.778106  0.469514  0

Диагональ должна быть равна нулю.


person vincet    schedule 19.08.2016    source источник
comment
Просто, к вашему сведению, julia не использует значения NA. У нас есть NaN   -  person Alexander Morley    schedule 19.08.2016
comment
x-ref: groups.google.com/forum/#!topic/ julia-users / VGbdlfbRfbc   -  person StefanKarpinski    schedule 19.08.2016
comment
Также рассмотрите возможность использования нулей вместо NA (или NaN). Почему? 1. Смысл линейной алгебры в основном теряется при использовании НА, и это препятствует любому использованию существующего кода линейной алгебры. 2. Известно, что НА являются заразными и генерирующими ошибки. Если вы еще раз опишете вариант использования, этот выбор станет более ясным.   -  person Dan Getz    schedule 19.08.2016


Ответы (3)


Вот что-то, вдохновленное Кодексом Стефана Карпински в списке пользователя Julia < / а>:

function vec2ltri_alt{T}(v::AbstractVector{T}, z::T=zero(T))
    n = length(v)
    v1 = vcat(0,v)
    s = round(Int,(sqrt(8n+1)-1)/2)
    s*(s+1)/2 == n || error("vec2utri: length of vector is not triangular")
    s+=1
    [ i>j ? v1[round(Int, j*(j-1)/2+i)] : (i == j ? z : NaN) for i=1:s, j=1:s ]
end

julia> vec2ltri_alt(collect(1:6))
4x4 Array{Any,2}:
 0  NaN  NaN  NaN
 1    0  NaN  NaN
 2    3    0  NaN
 3    4    6    0

Примечание. При желании ознакомьтесь с официальной документацией по тройному для большей ясности в том, что здесь происходит с синтаксисом ? ... :.

Для тех, кто ищет более "стандартное" решение с диагональной матрицей:

Вот версия, которая создает более стандартное решение:

function vec2ltri{T}(v::AbstractVector{T}, z::T=zero(T))
    n = length(v)
    s = round(Int,(sqrt(8n+1)-1)/2)
    s*(s+1)/2 == n || error("vec2utri: length of vector is not triangular")
    [ i>=j ? v[round(Int, j*(j-1)/2+i)] : z for i=1:s, j=1:s ]
end

a = vec2ltri(collect(1:6))

julia> a = vec2ltri(collect(1:6))
3x3 Array{Int64,2}:
 1  0  0
 2  3  0
 3  4  6

julia> istril(a)  ## verify matrix is lower triangular
true

Если вам нужен верхний треугольник: вместо нижнего, просто измените i<=j на i>=j.

Другие инструменты случайного выбора. Обратите внимание также на такие функции, как tril!(a), который преобразует заданную матрицу в нижний треугольник, заменяя все, что находится выше главной диагонали, нулями. Дополнительную информацию об этой функции см. В документации Джулии. как различные другие связанные инструменты.

person Michael Ohlrogge    schedule 19.08.2016

Возможно, вы захотите использовать понимание списка. Но было бы хорошо, если бы вы могли дать больше информации в вопросе о том, что вы пытаетесь сделать.

numrows =4
numcols = 4
[ x>y ? 1 : (x == y ? 0 : NaN) for x in 1:numrows, y in 1:numcols]

что даст:

 0  NaN  NaN  NaN
 1    0  NaN  NaN
 1    1    0  NaN
 1    1    1    0

Для любого количества строк и столбцов. И тогда вы можете работать оттуда.

См. Документацию для понимания списков и условных выражений:

http://docs.julialang.org/en/release-0.4/manual/arrays/#comprehensions

http://docs.julialang.org/en/release-0.4/manual/control-flow/#man-conditional-evaluation

person Alexander Morley    schedule 19.08.2016
comment
Теперь я хочу исследовать в цикле только нижнюю треугольную матрицу. Как я могу сделать это эффективно, сформировать точку зрения быстрой оптимизации, потому что у меня матрица 5000 на 5000. Благодарность - person vincet; 22.08.2016

Принятое решение не индексирует все элементы вектора по порядку, а выходная матрица имеет повторяющиеся элементы. Формула неверна. Вот мое предложение, вдохновленное предыдущими ответами:

Для нижнетреугольной матрицы:

function vec2ltri{T}(v::Vector{T})
    d = length(v)
    n = Int((sqrt(8d+1)+1)/2)
    n*(n-1)/2 == d || error("vec2ltri: length of vector is not triangular")
    [ i>j ? v[Int((2n-j)*(j-1)/2)+i-j] : 0 for i=1:n, j=1:n ]
end

который выведет:

julia> vec2ltri(collect(1:6))
4×4 Array{Int64,2}:
 0  0  0  0
 1  0  0  0
 2  4  0  0
 3  5  6  0

Для верхней треугольной матрицы:

function vec2utri{T}(v::Vector{T})
    d = length(v)
    n = Int((sqrt(8d+1)+1)/2)
    n*(n-1)/2 == d || error("vec2utri: length of vector is not triangular")
    [ i<j ? v[Int((j-1)*(j-2)/2)+i] : 0 for i=1:n, j=1:n ]
end

который выведет:

julia> vec2utri(collect(1:6))
4×4 Array{Int64,2}:
 0  1  2  4
 0  0  3  5
 0  0  0  6
 0  0  0  0
person Zranz    schedule 15.06.2018