2015-01-05 9 views
15

से मेल नहीं खाता एकवचन मूल्य अपघटन एम = यूएसवी * पर विचार करें। फिर एम * एम के eigenvalue अपघटन एम * एम = वी (एस * एस) वी * = वीएस * यू * यूएसवी * देता है। मैं दिखा रहा है कि eigenvectors eigh समारोह से वापस लौटे svd समारोह से लौट आए उन जैसे ही हैं द्वारा numpy के साथ इस समानता की पुष्टि करना चाहते:एग्नेवेक्टरों ने numpy के साथ गणना की और svd

import numpy as np 
np.random.seed(42) 
# create mean centered data 
A=np.random.randn(50,20) 
M= A-np.array(A.mean(0),ndmin=2) 

# svd 
U1,S1,V1=np.linalg.svd(M) 
S1=np.square(S1) 
V1=V1.T 

# eig 
S2,V2=np.linalg.eigh(np.dot(M.T,M)) 
indx=np.argsort(S2)[::-1] 
S2=S2[indx] 
V2=V2[:,indx] 

# both Vs are in orthonormal form 
assert np.all(np.isclose(np.linalg.norm(V1,axis=1), np.ones(V1.shape[0]))) 
assert np.all(np.isclose(np.linalg.norm(V1,axis=0), np.ones(V1.shape[1]))) 
assert np.all(np.isclose(np.linalg.norm(V2,axis=1), np.ones(V2.shape[0]))) 
assert np.all(np.isclose(np.linalg.norm(V2,axis=0), np.ones(V2.shape[1]))) 

assert np.all(np.isclose(S1,S2)) 
assert np.all(np.isclose(V1,V2)) 

पिछले दावे विफल रहता है। क्यूं कर?

+0

आप जोड़ सकते हैं सभी विकर्ण तत्वों के लिए एक सकारात्मक संख्या, यानी एम 2 = एम + ए * I बनाते हैं, जहां एम 2 पॉजिटिव सेमीफाइडफाइट बनाने के लिए काफी बड़ा होता है। फिर एसवीडी और आठ से बेहतर सहमत होना चाहिए। –

उत्तर

14

बस अपनी समस्या को डीबग करने के लिए छोटी संख्याओं के साथ खेलें।

आकार (50,20)

मेरी यादृच्छिक मामले में के साथ अपने बहुत बड़ा मेट्रिक्स के बजाय A=np.random.randn(3,2) के साथ शुरू, मुझे लगता है कि

v1 = array([[-0.33872745, 0.94088454], 
    [-0.94088454, -0.33872745]]) 

और v2 के लिए:

v2 = array([[ 0.33872745, -0.94088454], 
    [ 0.94088454, 0.33872745]]) 

वे केवल के लिए अलग एक संकेत, और जाहिर है, यहां तक ​​कि अगर यूनिट मॉड्यूल के लिए सामान्यीकृत हो, तो वेक्टर एक संकेत के लिए भिन्न हो सकता है।

अब आप अपने मूल बड़ा मैट्रिक्स के लिए चाल की कोशिश करता है, तो

assert np.all(np.isclose(V1,-1*V2)) 

, यह विफल रहता है ... फिर, यह ठीक है। क्या होता है कि कुछ वैक्टरों को -1 से गुणा किया गया है, कुछ अन्य नहीं हैं।

वैक्टर के बीच समानता के लिए जाँच करने के लिए एक सही तरीका है:

assert allclose(abs((V1*V2).sum(0)),1.) 

और वास्तव में, यह कैसे काम करता है आप की भावना प्राप्त करने के लिए इस मात्रा मुद्रित कर सकते हैं:

(V1*V2).sum(0) 

कि वास्तव में या तो +1 या -1 वेक्टर पर निर्भर करता है:

array([ 1., -1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 
    1., -1., 1., 1., 1., -1., -1.]) 

संपादित करें: यह ज्यादातर मामलों में होगा, खासकर यदि एक यादृच्छिक मैट्रिक्स से शुरू होता है। लेकिन ध्यान दें कि इस परीक्षण की संभावना के रूप में नीचे उसकी टिप्पणी में @Sven Marnach द्वारा बताया असफल हो जायेगी अगर एक या अधिक eigenvalues ​​आयाम 1 से बड़ा का एक eigenspace है,:

वहाँ अन्य मतभेद अभी से गुणा वैक्टर से हो सकता है -1। eigenvalues ​​में से किसी एक बहु-आयामी eigenspace है, तो आप कि eigenspace की एक मनमाना orthonormal आधार मिल सकता है, और लिए इस तरह के ठिकानों एक arbitraty एकजुट मैट्रिक्स द्वारा एक दूसरे के खिलाफ घुमाया जा सकता है

+0

@matus ठीक है, मैं खो गया हूं :) लेकिन मुझे आपके फैसले पर भरोसा है, और इसलिए मैं अपनी टिप्पणियों को हटा दूंगा ताकि भावी पाठकों को भ्रमित न किया जा सके। चीयर्स! – BartoszKP

+0

-1 से गुणा वैक्टरों की तुलना में अन्य अंतर हो सकते हैं।यदि किसी भी ईजिनवेल्स में बहु-आयामी ईजेन्स स्पेस है, तो आपको उस ईगेंस स्पेस का मनमाना आधारभूत आधार मिल सकता है, और ऐसे अड्डों को एक दूसरे के खिलाफ मध्यस्थता इकाई मैट्रिक्स द्वारा घूर्णन किया जा सकता है। –

+0

@SvenMarnach, यह एक बहुत ही मान्य बिंदु है। मैं इस चेतावनी को इंगित करने के लिए पोस्ट को संपादित करूंगा – gg349

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