2010-10-18 7 views
40

मान लीजिए मैं एक NxN मैट्रिक्स A, एक सूचकांक वेक्टर संख्या 1 के एक सबसेट से मिलकर वी है: लागू नहीं है, और एक मूल्य के कश्मीर, और मैं ऐसा करना चाहते हैं:विकर्ण पर मूल्य कैसे असाइन करें?

for i = V 
    A(i,i) = K 
end 

वहाँ ऐसा करने के लिए एक रास्ता है यह एक कथन w/vectorization में?

उदा। ए (कुछ) = के

कथन A(V,V) = K काम नहीं करेगा, यह ऑफ-विकर्ण तत्वों को निर्दिष्ट करता है, और यह वही नहीं है जो मैं चाहता हूं। उदाहरण के लिए:

>> A = zeros(5); 
>> V = [1 3 4]; 
>> A(V,V) = 1 

A = 

1  0  1  1  0 
0  0  0  0  0 
1  0  1  1  0 
1  0  1  1  0 
0  0  0  0  0 

उत्तर

60

मैं आमतौर पर उस के लिए EYE का उपयोग करें:

A = magic(4) 
A(logical(eye(size(A)))) = 99 

A = 
    99  2  3 13 
    5 99 10  8 
    9  7 99 12 
    4 14 15 99 

वैकल्पिक रूप से, आप बस रैखिक सूचकांकों की सूची, एक विकर्ण तत्व से के बाद से अगले करने के लिए बना सकते हैं, यह nRows+1 कदम उठा लेता:

[nRows,nCols] = size(A); 
A(1:(nRows+1):nRows*nCols) = 101 
A = 
    101  2  3 13 
    5 101 10  8 
    9  7 101 12 
    4 14 15 101 

आप केवल विकर्ण तत्वों के एक सबसेट उपयोग करना चाहते हैं, तो आप विकर्ण सूचकांक की एक सूची बनाने की जरूरत:

subsetIdx = [1 3]; 
diagonalIdx = (subsetIdx-1) * (nRows + 1) + 1; 
A(diagonalIdx) = 203 
A = 
    203  2  3 13 
    5 101 10  8 
    9  7 203 12 
    4 14 15 101 

वैकल्पिक रूप से, आप एक तार्किक सूचकांक सरणी diag का उपयोग कर बना सकते हैं (वर्ग सरणियों के लिए ही काम करता है)

diagonalIdx = false(nRows,1); 
diagonalIdx(subsetIdx) = true; 
A(diag(diagonalIdx)) = -1 
A = 
    -1  2  3 13 
    5 101 10  8 
    9  7 -1 12 
    4 14 15 101 
+0

शांत है, यह काम करता है! स्वीकार करेंगे जब बेवकूफ-टाइमर –

+0

@ जेसन एस चलाता है: धन्यवाद! मुझे वास्तव में यह एक परेशान मुद्दा मिल गया है; मैं अक्सर पिछले उदाहरणों के लिए 'eye' – Jonas

+0

का उपयोग करना याद रखने से पहले, 'डायग' का उपयोग करने का प्रयास करता हूं, मैं पूर्ण सूचकांक खोजने के लिए मैटलैब के सब 2ind फ़ंक्शन का उपयोग करने का सुझाव देता हूं। मेरी राय में, यह सबसे सीधा-आगे (और सबसे अधिक पढ़ने योग्य) दृष्टिकोण है और आपके पिछले दो सुझावों को प्रतिस्थापित कर सकता है। – tc88

21
>> tt = zeros(5,5) 
tt = 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
>> tt(1:6:end) = 3 
tt = 
    3  0  0  0  0 
    0  3  0  0  0 
    0  0  3  0  0 
    0  0  0  3  0 
    0  0  0  0  3 

और अधिक सामान्य:

>> V=[1 2 5]; N=5; 
>> tt = zeros(N,N); 
>> tt((N+1)*(V-1)+1) = 3 
tt = 
    3  0  0  0  0 
    0  3  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  0  3 

इस पर आधारित है तथ्य यह है कि मैट्रिस को एक-आयामी सरणी (वैक्टर) के रूप में एक्सेस किया जा सकता है, जहां 2 सूचकांक (एम, एन) को रैखिक मैपिंग एम * एन + एन द्वारा प्रतिस्थापित किया जाता है।

+0

मैंने अपना संपादन सबमिट करने के बाद ही आपके समाधान को देखा। तेजी से होने के लिए +1, भले ही मेरा समाधान थोड़ा अधिक सामान्य है :) – Jonas

+1

मुझे वास्तव में टीटी (1: एन + 1: अंत) विधि पसंद है, वास्तव में साफ! – Erika

2
A = zeros(7,6); 
V = [1 3 5]; 

[n m] = size(A); 
diagIdx = 1:n+1:n*m; 
A(diagIdx(V)) = 1 

A = 
    1  0  0  0  0  0 
    0  0  0  0  0  0 
    0  0  1  0  0  0 
    0  0  0  0  0  0 
    0  0  0  0  1  0 
    0  0  0  0  0  0 
    0  0  0  0  0  0 
2

मान लीजिए के मूल्य है। आदेश

A=A-diag(K-diag(A)) 

थोड़ा तेजी से

>> A=randn(10000,10000); 

>> tic;A(logical(eye(size(A))))=12;toc 

बीता हुआ समय .५,१७,५७५ सेकंड है हो सकता है।

>> tic;A=A+diag((99-diag(A)));toc 

विलुप्त समय 0.353408 सेकंड है।

लेकिन यह अधिक स्मृति का उपभोग करता है।

+0

मैंने 'ए (तार्किक (आंख (आकार (ए)) का उपयोग किया)) = के' लचीला तेज़ और भरोसेमंद – Vass

1

मैं sub2ind का उपयोग करें और के रूप में दोनों x और y मापदंडों विकर्ण सूचकांक दे देते हैं:

A = zeros(4) 
V=[2 4] 

idx = sub2ind(size(A), V,V) 
% idx = [6, 16] 

A(idx) = 1 

% A = 
% 0  0  0  0 
% 0  1  0  0 
% 0  0  0  0 
% 0  0  0  1