2014-07-19 11 views
8

को देखते हुए दो मैट्रिक्सअजगर - मैट्रिक्स बाहरी उत्पाद

A: m * r 
B: n * r 

मैं प्रत्येक प्रविष्टि C_ij एक मैट्रिक्स A_i और B_j के बाहरी उत्पाद द्वारा गणना होने के साथ, एक और मैट्रिक्स C: m * n उत्पन्न करना चाहते हैं।

उदाहरण के लिए,

A: [[1, 2], 
    [3, 4]] 

B: [[3, 1], 
    [1, 2]] 

देता

C: [[[3, 1], [[1 ,2], 
    [6, 2]], [2 ,4]], 
    [9, 3], [[3, 6], 
    [12,4]], [4, 8]]] 

मैं छोरों के लिए उपयोग कर ऐसा कर सकते हैं, जैसे

for i in range (A.shape(0)): 
     for j in range (B.shape(0)): 
     C_ij = np.outer(A_i, B_j) 

मुझे आश्चर्य है कि अगर इस गणना करने का एक vectorised तरीका है इसे तेज करने के लिए?

+2

आप एक 4D, '(एम, एन, आर, आर)' -shape सरणी, चाहते हैं या आप एक 2D, 'चाहते हो करो (एम, एन) '' ऑब्जेक्ट 'प्रकार का शेप सरणी जहां प्रत्येक तत्व एक और सरणी है? मैं दृढ़ता से पहले विकल्प की सिफारिश करता हूं, लेकिन आपका वर्णन दूसरे के करीब लगता है। – user2357112

+0

भ्रम के लिए खेद है, लेकिन मैं पहले व्यक्ति को पसंद करता हूं, एक 4 डी '(एम, एन, आर, आर)' -शिप सरणी। –

उत्तर

6
temp = numpy.multiply.outer(A, B) 
C = numpy.swapaxes(temp, 1, 2) 

NumPy ufuncs, एक outer विधि लगभग करता है कि आप क्या चाहते हैं। निम्नलिखित:

temp = numpy.multiply.outer(A, B) 

परिणाम उत्पन्न करता है जैसे temp[a, b, c, d] == A[a, b] * B[c, d]। आप C[a, b, c, d] == A[a, c] * B[b, d] चाहते हैं। swapaxes कॉल को पुन: व्यवस्थित करता है temp इसे इच्छित क्रम में रखने के लिए।

0

numpy का उपयोग करें;

In [1]: import numpy as np 

In [2]: A = np.array([[1, 2], [3, 4]]) 

In [3]: B = np.array([[3, 1], [1, 2]]) 

In [4]: C = np.outer(A, B) 

In [5]: C 
Out[5]: 
array([[ 3, 1, 1, 2], 
     [ 6, 2, 2, 4], 
     [ 9, 3, 3, 6], 
     [12, 4, 4, 8]]) 

एक बार जब आप इच्छित परिणाम है, तो आप लगभग किसी भी आकार आप चाहते हैं यह मोल्ड करने के लिए numpy.reshape() उपयोग कर सकते हैं; इस तरह के multiply रूप

In [6]: C.reshape([4,2,2]) 
Out[6]: 
array([[[ 3, 1], 
     [ 1, 2]], 

     [[ 6, 2], 
     [ 2, 4]], 

     [[ 9, 3], 
     [ 3, 6]], 

     [[12, 4], 
     [ 4, 8]]]) 
+0

मुझे आश्चर्य है कि ओपी चाहता है कि यह इतनी नज़दीक है, लेकिन समानता के बावजूद, यह अभी भी सही नहीं है। यदि आप वांछित परिणाम को कोशिकाओं में 2 डी ग्रिड के साथ एक बड़े 2 डी ग्रिड के रूप में देखते हैं, तो यह एक ग्रिड बनाने के लिए किनारों पर सभी छोटे ग्रिड को एक साथ जोड़कर आपको मिल जाएगा। – user2357112

+0

हां, आपसे सहमत हैं। शायद पहले 'np.outer (ए, बी) 'करें और फिर इसे छोटे ग्रिड में विभाजित करें? –

+0

लेकिन यह एक अलग परिणाम देगा। मैं चाहता था कि आंतरिक मैट्रिस '[[3, 1], [6, 2]]', '[[1, 2], [2, 4]] ',' [[9, 3], [12, 4]] 'और' [[3, 6], [4, 8]] '। –

13

आइंस्टीन अंकन इस समस्या को व्यक्त करता है अच्छी तरह से

In [85]: np.einsum('ac,bd->abcd',A,B) 
Out[85]: 
array([[[[ 3, 1], 
     [ 6, 2]], 

     [[ 1, 2], 
     [ 2, 4]]], 


     [[[ 9, 3], 
     [12, 4]], 

     [[ 3, 6], 
     [ 4, 8]]]]) 
+0

मैन, मुझे उस नोटेशन को सीखना चाहिए। प्रत्येक बार जब कोई इसका उपयोग कर उत्तर देता है, तो यह हमेशा से कम होता है जो मैं साथ आता हूं। यदि आप आइंस्टीन सम्मेलन सम्मेलन को जानते हैं तो शायद अधिक समझने योग्य भी। – user2357112

संबंधित मुद्दे