I believe this work-in-progress type may be adapted? I wanted to make this
faster by using tuples or immutable fixed vectors to store the data or
whatnot, but I guess I'm currently stuck. Help wanted.
Compared to looping unnecessarily over a full matrix, this speeds things up
by around 35%.
immutable Maq7 <:AbstractMatrix{Int}
data::Array{Int64,2} # upper triangular except diagonal, stored as a
horizontal vector
width::Int64
function Maq7(mat::Matrix{Int64})
if issym(mat)
n=size(mat,1)
if n>1
v=mat[2:n,1]
for col = 2:(n-1)
append!(v,mat[(col+1):n,col])
end
new(v', size(mat,1))
else
error("Ouch, not > (1x1)")
end
else
error("Ouch, not square symmetric")
end
end
end
Base.size(A::Maq7)= A.width, A.width
Base.length(A::Maq7)= div(A.width*(A.width-1), 2)
Base.getindex(A::Maq7, i::Int) = Base.getindex(A.data, i)
function Base.getindex(A::Maq7, r::Int , c::Int )
if c > r
return getindex(A.data, div( (r-1)*(2*A.width -r) , 2 ) + c - r )
elseif r > c
return getindex(A.data, div( (c-1)*(2*A.width -c) , 2 ) + r - c )
else
return zero(eltype(A.data))
end
end
Base.linearindexing(::Type{Maq7}) = Base.LinearFast()
Example:
julia> ms
4x4 Array{Int64,2}:
7 1 2 3
1 8 4 5
2 4 9 6
3 5 6 10
julia> m=Maq7(ms)
4x4 Maq7:
0 1 2 3
1 0 4 5
2 4 0 6
3 5 6 0
julia> collect(m)
6-element Array{Int64,1}:
1
2
3
4
5
6
julia> length(m)
6