How to transfer a vector from upper triangular matrix to the original symmetric matrix?

Viewed 308

I have a very large symmetric matrix called M. The size of the matrix M is 1000000 * 1000000. Let M[i,j] denote the element at ith row and jth column of matrix M. The upper triangular part of the symmetric matrix M was saved as a vector called V. V = [M[1,1], M[1,2], M[2,2], M[1,3], M[2,3], M[3,3], M[1,4], M[2,4], M[3,4], M[4,4] ,..., M[1000000, 1000000]]. I had three questions.

(1) How can I convert V to M efficiently?

(2) How can I convert V to the upper triangular part of the symmetric matrix M efficiently? I mean convert V to another matrix W. The upper triangular part of W is the same as M while the other elements in W is 0.

(3) How can I convert V to the lower triangular part of the symmetric matrix M efficiently? I mean convert V to another matrix Q. The lower triangular part of Q is the same as M while the other elements in Q is 0.

1 Answers

In this case the most efficient way to create M is to have a custom type that is <:AbstractMatrix. This should be almost zero overhead and use no extra memory.

The type would be something like:

struct MyMatrix{S, T<:AbstractVector{S}} <: AbstractMatrix{S}
    v::T
end

(I am omitting a constructor which should check if length of v matches the "half" of some square matrix)

Then you should define the appropriate methods for your type. Their list is given here in the Julia manual (and depending on the exact type of a matrix you want they should be implemented differently). In that section there is an example how such an object can be implemented.

Related