2017-01-21 1 views
2

ich folgende Matrices haben:Matrix Kombinationslogik in einer numpythonic Weise

,

und

.

Wo Jedes Element eine 3x3-Matrix ist (d. H. A_01 ist eine 3x3-Matrix). Dies bedeutet, dass die A- und B-Tensoren 9x9-Matrizen sind. Nicht für Befehle, wie kann ich die vorherigen Gleichungen kombinieren, um zu erhalten:

.

Das Ziel ist es, eine numpythonic Lösung, weil in realen Fällen zu erhalten A und B Matrizen mit einer Größe von (N, N) haben können.

+0

Also, mit A und B als '(N, N)' wäre noch jedes Element '3 x 3'? – Divakar

+0

Jeder A und B ist ein 3x3 Tensor. Dies wird als Tensor nach Blöcken bezeichnet, wobei jedes Element ein anderer Tensor ist. – NunodeSousa

+0

Also, es wäre 3 x 3 = 9 Blöcke in jedem A und B immer? – Divakar

Antwort

3

Sie könnten versuchen, so etwas wie

import numpy as np 

def checker_index(n, m=3): 
    """create an index vector that addresses m blocks of n consecutive 
    elements with the blocks separated by gaps of n elements 
    """ 
    # the next line creates the array 
    #/ 0 1 ... n-1 \ 
    # | 2n 2n+1 ... 3n-1 | 
    # \ 4n 4n+1 ... 5n-1/
    i = np.arange(m*n).reshape((m, n)) + n*np.arange(m)[:, None] 
    # next line just puts the rows side by side 
    # now observe the these are precisely the places where you want to 
    # put your first row of of A's (with a leading id) in the first 
    # row of the target structure, and similarly with columns 
    # also, observe that one just needs to add n to get indices 
    # suitable for placing the first row/column of B's 
    return i.ravel() 

def mingle(AA, BB, m=3): 
    """combine AA and BB into the target structure 

    here AA and BB are the full 3x3 block matrices you define in 
    your question 
    """ 
    n = len(AA) // m 
    i1 = checker_index(n, m) 
    # ix_ creates an "open grid" from its arguments 
    # so indexing with y1, x1 below will select nm x nm elements 
    # contrast this with ... 
    y1, x1 = np.ix_(i1, i1) 
    i2 = i1 + n 
    y2, x2 = np.ix_(i2, i2) 

    IAA = AA.copy() 
    # ... the following line which only selects the diagonal, 
    # thus just mn elements 
    IAA[np.arange(m*n), np.arange(m*n)] = 1 
    out = np.empty((2*m*n, 2*m*n)) 
    out[y1, x1] = IAA 
    out[y1, x2] = BB 
    out[y2, x1] = BB 
    out[y2, x2] = IAA 
    return out 

Numpythonic genug?

1

Hier ist ein Ansatz -

def matrix_combination(A,B): 
    N = A.shape[0]//3 # Size of each block 
    A4D = A.reshape(3,N,3,N) 
    B4D = B.reshape(3,N,3,N) 

    r,c = np.nonzero(~np.eye(3,dtype=bool)) 
    out = np.zeros((6,N,6,N),dtype=A.dtype)  

    idx0 = 2*np.arange(3) 
    out[idx0[r],:,idx0[c]] = A4D[r,:,c] 
    out[idx0[r]+1,:,idx0[c]+1] = A4D[r,:,c] 

    out[idx0[r],:,idx0[c]+1] = B4D[r,:,c] 
    out[idx0[r]+1,:,idx0[c]] = B4D[r,:,c] 
    out = out.reshape(N*6,-1) 
    np.fill_diagonal(out,1) 
    return out 

Probelauf -

In [41]: A 
Out[41]: 
array([[ 0, 0, 44, 98, 40, 69], 
     [ 0, 0, 22, 55, 51, 19], 
     [16, 58, 0, 0, 95, 95], 
     [90, 88, 0, 0, 47, 91], 
     [65, 96, 21, 50, 0, 0], 
     [15, 91, 23, 91, 0, 0]]) 

In [42]: B 
Out[42]: 
array([[ 0, 0, 20, 36, 85, 15], 
     [ 0, 0, 17, 78, 56, 55], 
     [86, 19, 0, 0, 60, 96], 
     [76, 30, 0, 0, 34, 36], 
     [73, 63, 28, 58, 0, 0], 
     [40, 19, 22, 96, 0, 0]]) 

In [43]: matrix_combination(A,B) 
Out[43]: 
array([[ 1, 0, 0, 0, 44, 98, 20, 36, 40, 69, 85, 15], 
     [ 0, 1, 0, 0, 22, 55, 17, 78, 51, 19, 56, 55], 
     [ 0, 0, 1, 0, 20, 36, 44, 98, 85, 15, 40, 69], 
     [ 0, 0, 0, 1, 17, 78, 22, 55, 56, 55, 51, 19], 
     [16, 58, 86, 19, 1, 0, 0, 0, 95, 95, 60, 96], 
     [90, 88, 76, 30, 0, 1, 0, 0, 47, 91, 34, 36], 
     [86, 19, 16, 58, 0, 0, 1, 0, 60, 96, 95, 95], 
     [76, 30, 90, 88, 0, 0, 0, 1, 34, 36, 47, 91], 
     [65, 96, 73, 63, 21, 50, 28, 58, 1, 0, 0, 0], 
     [15, 91, 40, 19, 23, 91, 22, 96, 0, 1, 0, 0], 
     [73, 63, 65, 96, 28, 58, 21, 50, 0, 0, 1, 0], 
     [40, 19, 15, 91, 22, 96, 23, 91, 0, 0, 0, 1]]) 
1

Gerade für den Spaß von ihm (und auf ein bis Divakar) hier ist eine sehr kompakte Lösung:

def mingle(AA, BB, m=3): 
    n = len(AA) // m 
    out = np.empty((m, 2, n, m, 2, n)) 
    out[:, [0, 1], ..., [0, 1], :] = AA.reshape((1, m, n, m, n)) 
    out[:, [0, 1], ..., [1, 0], :] = BB.reshape((1, m, n, m, n)) 
    out.shape = m * 2 * n, m * 2 * n 
    out[np.arange(m * 2 * n), np.arange(m * 2 * n)] = 1 
    return out 
+0

Nett, ich dachte in diese Richtung, konnte einfach nicht Beende es. – Divakar

+0

@Divakar Danke, offensichtlich inspiriert von Ihrer Lösung. –

Verwandte Themen