2016-04-24 8 views
5

के लिए ऋणात्मक eigenvalues ​​देता है मुझे सकारात्मक semidefinite matrices के लिए नकारात्मक eigenvalues ​​वापस scipy eigh समारोह के साथ कुछ समस्याएं हैं। नीचे एक MWE है।scipy eigh सकारात्मक semidefinite मैट्रिक्स

hess_R फ़ंक्शन सकारात्मक पॉजिटिव सेमीडिफिन मैट्रिक्स देता है (यह एक रैंक एक मैट्रिक्स और एक विकर्ण मैट्रिक्स का योग है, दोनों गैर-अनुवांशिक प्रविष्टियों के साथ)।

import numpy as np 
from scipy import linalg as LA 

def hess_R(x): 
    d = len(x) 
    H = np.ones(d*d).reshape(d,d)/(1 - np.sum(x))**2 
    H = H + np.diag(1/(x**2)) 
    return H.astype(np.float64) 

x = np.array([ 9.98510710e-02 , 9.00148922e-01 , 4.41547488e-10]) 
H = hess_R(x) 
w,v = LA.eigh(H) 
print w 

eigenvalues ​​मुद्रित

[ -6.74055241e-271 4.62855397e+016 5.15260753e+018] 

हैं मैं hess_R की वापसी बयान में np.float32 साथ np.float64 की जगह मैं

[ -5.42905303e+10 4.62854925e+16 5.15260506e+18] 

बजाय मिलता है, तो मैं इस अनुमान लगा रहा हूँ के कुछ प्रकार है सटीक मुद्दा।

क्या इसे ठीक करने का कोई तरीका है? तकनीकी रूप से मुझे आठों का उपयोग करने की आवश्यकता नहीं है, लेकिन मुझे लगता है कि यह मेरी अन्य त्रुटियों के साथ अंतर्निहित समस्या है (इन मैट्रिस की स्क्वायर जड़ों को लेना, NaNs प्राप्त करना आदि)

+0

यदि मैं 'LA.eigh' के बजाय 'LA.eig' का उपयोग करता हूं, तो मुझे अलग-अलग eigenvalues ​​मिलते हैं:' [5.15260753e + 18 + 0.j 3.22785571e + 01 + 0.j 4.62855397e + 16 + 0.j ] ' – Peaceful

+2

आईएमएचओ, आपका 'हेस_आर' फ़ंक्शन वास्तविक हेसियन मैट्रिक्स वापस नहीं करता है। तो आपके मामले में 'आठवां वापसी झूठी परिणाम। –

+0

@ बीएम। क्या आप आगे बता सकते हैं कि आपका क्या मतलब है? इसके बजाय फ़ंक्शन लौटने वाला क्या है? – angryavian

उत्तर

0

मुझे लगता है कि समस्या यह है कि आपने हिट किया है फ्लोटिंग-पॉइंट परिशुद्धता की सीमाएं। रैखिक बीजगणित परिणामों के लिए एक अच्छा नियम-अंगूठे यह है कि वे फ्लोट 32 के लिए 10^8 में लगभग एक भाग के लिए अच्छे हैं, और फ्लोट 64 के लिए 10^16 में लगभग एक हिस्सा हैं। ऐसा लगता है कि आपके सबसे छोटे से सबसे बड़े अनुपात यहां eigenvalue 10^-16 से कम है। इस वजह से, लौटाया मूल्य वास्तव में भरोसा नहीं किया जा सकता है और आपके द्वारा उपयोग किए जाने वाले ईजीनवे क्रियान्वयन के विवरण पर निर्भर करेगा।

उदाहरण के लिए, यहां चार अलग-अलग हलकों को उपलब्ध होना चाहिए; उनके परिणाम पर एक नज़र डालें:

# using the 64-bit version 
for impl in [np.linalg.eig, np.linalg.eigh, LA.eig, LA.eigh]: 
    w, v = impl(H) 
    print(np.sort(w)) 
    reconstructed = np.dot(v * w, v.conj().T) 
    print("Allclose:", np.allclose(reconstructed, H), '\n') 

आउटपुट:

[ -3.01441754e+02 4.62855397e+16 5.15260753e+18] 
Allclose: True 

[ 3.66099625e+02 4.62855397e+16 5.15260753e+18] 
Allclose: True 

[ -3.01441754e+02+0.j 4.62855397e+16+0.j 5.15260753e+18+0.j] 
Allclose: True 

[ 3.83999999e+02 4.62855397e+16 5.15260753e+18] 
Allclose: True 

सूचना वे सब बड़े दो eigenvalues ​​पर सहमत हैं, लेकिन उस कार्यान्वयन के लिए कार्यान्वयन से छोटी से छोटी eigenvalue परिवर्तन का मूल्य। फिर भी, सभी चार मामलों में इनपुट मैट्रिक्स को 64-बिट परिशुद्धता तक पुनर्निर्मित किया जा सकता है: इसका अर्थ यह है कि एल्गोरिदम उनके लिए उपलब्ध सटीकता तक अपेक्षित कार्य कर रहे हैं।

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