ttpy icon indicating copy to clipboard operation
ttpy copied to clipboard

How to reshape a matrix to a vector

Open rborrelli opened this issue 7 years ago • 8 comments

Is it possible to use the implemented reshape function to reshape a matrix to a vector? I have a matrix A(i_1, ...i_d, j_1...j_d) in TT format and I want to reshape it to a vector with the following structure:

A = A_1(i_1,j_1) A_2(i_2,j_2) ... -> B_1(i_1) B_1(i_2)...B_d(i_d) B_{d+1}(j_1) ...B_{2d}(j_d)

The reshape function of a matrix seems to work only with a pair of indices, and I cannot find an example of tensor reshaping.

Thanks.

rborrelli avatar May 28 '18 08:05 rborrelli

This sounds more like a "permute" than a "reshape". You can do what you want by first splitting each core A_k(i_k, j_k) into two consecutive cores B_k(i_k) C_k(j_k), then move all B cores to the beginning and all C cores to the end using ttpy's new permute() function from the tools.py module.

rballester avatar May 28 '18 08:05 rballester

This can be done using combination of reshape and permute functions (both are in tools.py):

def mat2vec(A):
    crs_mat = tt.matrix.to_list(A)
    crs_vec = []
    for cr in crs_mat:
        r1, n, m, r2 = cr.shape
        crs_vec.append(cr.reshape(r1, n*m, r2, order='f'))
    return tt.vector.from_list(crs_vec)

n = 2
d = 6
A = tt.eye([n]*d)
A = mat2vec(A)
A = tt.reshape(A, [2]*2*d)
A = tt.permute(A, range(0, 2*d, 2) + range(1, 2*d+1, 2), 1e-10)

P.S.: permuting the identity matrix this way is a bad idea, but still :)

rakhuba avatar May 28 '18 08:05 rakhuba

Thanks, I had an old version of the code without the permute function which seems to do exactly what I need. Since I am using a locally modified version of ttpy is it safe to extract the permute() function from tools.py? or does it depend on other modifications of the code? (I see now the code use the six module but I'd like to keep the old version, to avoid a problem of overflow in svd decomposition).

Raffaele

rborrelli avatar May 28 '18 09:05 rborrelli

tt.permute does not utilize anything besides standard numpy functions. So no problem to simply copy it.

Note however, that it contains vector.from_list(cores), which can be simply replaced by tensor.from_list in case you use a very old version.

rakhuba avatar May 28 '18 09:05 rakhuba

Thanks again. BTW, the modification I added to avoid problems in svd might also be of help. It is a very naive rescaling of the R matrix in the QR decomposition. In dtt_ort() I modified the call the call to dorgq() subroutine in this way :

umax = maxval(abs(mat(1:(min(nn,mm)+(nn-1)mn)))) ! new line mat = mat/umax ! new line call dorgqr(mm,mn,mn,u,mm,tau,work,lwork,info) u(1:mmmn) = u(1:mm*mn)*umax !new line

I did something similar in ztt_ort(). I know it is not the best rescaling (but it works when you have arrays with a really high dimensionality.)

rborrelli avatar May 28 '18 09:05 rborrelli

@rakhuba since you mentioned it, what would be the best way to permute indices for the identity matrix? I just realized that I the matrix I am trying to reshape/permute has a lot of Kronecker products of identity matrices. Thanks a lot

rborrelli avatar May 29 '18 12:05 rborrelli

The problem is that in my example the resulting matrix will have full rank independently of the method you choose to get it. I do not know your particular application, so there is not much can be said here.

rakhuba avatar May 29 '18 12:05 rakhuba

Indeed that reshape has full rank. Once I realized it I reformulated my entire problem to avoid the reshape/permute operations. Thanks for the hints.

rborrelli avatar May 29 '18 13:05 rborrelli