This may also be a case where writing an iterator that just visits the
elements with i >= j might be what you want. You can study the implementation
of CartesianIndex in Base for inspiration.
--Tim
On Saturday, November 14, 2015 02:18:45 PM hustf wrote:
> 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