python - अंडाकार मनमाना सटीक रेखीय बीजगणित




math numpy (4)

मेरे पास एक अंडाकार 2 डी सरणी है [मध्यम / बड़े आकार की - 500x500 कहें] मैं इसके तत्व-प्रतिद्वंद्वी के eigenvalues ​​खोजना चाहता हूँ समस्या यह है कि कुछ मान काफी नकारात्मक हैं (-800, -1000, आदि), और उनके एक्सपोनेंट्स अंडरफ्लो (जिसका अर्थ है कि वे शून्य के करीब हैं, इसलिए उन्हें शून्य के रूप में मानते हैं)। क्या नैमितिकी में मनमाना सटीकता का उपयोग करने के लिए वैसे भी है?

जिस तरह से मैं इसे सपना:

import numpy as np

np.set_precision('arbitrary') # <--- Missing part
a = np.array([[-800.21,-600.00],[-600.00,-1000.48]])
ex = np.exp(a)  ## Currently warns about underflow
eigvals, eigvecs = np.linalg.eig(ex)

मैंने gmpy और mpmath के साथ कोई समाधान नहीं खोज लिया है किसी भी विचार का स्वागत किया जाएगा


SymPy मनमाना सटीक गणना कर सकते हैं:

from sympy import exp, N, S
from sympy.matrices import Matrix

data = [[S("-800.21"),S("-600.00")],[S("-600.00"),S("-1000.48")]]
m = Matrix(data)
ex = m.applyfunc(exp).applyfunc(lambda x:N(x, 100))
vecs = ex.eigenvects()
print vecs[0][0] # eigen value
print vecs[1][0] # eigen value
print vecs[0][2] # eigen vect
print vecs[1][2] # eigen vect

उत्पादन:

-2.650396553004310816338679447269582701529092549943247237903254759946483528035516341807463648841185335e-261
2.650396553004310816338679447269582701529092549943247237903254759946483528035516341807466621962539464e-261
[[-0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999994391176386872]
[                                                                                                      1]]
[[1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000560882361313]
[                                                                                                    1]]

आप एन (एक्स, 100) में 100 को दूसरे परिशुद्धता में परिवर्तित कर सकते हैं, लेकिन, जैसा कि मैंने 1000 की कोशिश की है, ईईजीन वक्र की गणना विफल रही।


जहाँ तक मुझे पता है, numpy दोहरे सटीक (फ्लोट 64) से अधिक का समर्थन नहीं करता है, जो कि निर्दिष्ट नहीं है अगर डिफ़ॉल्ट है

इसे प्रयोग करने का प्रयास करें: http://code.google.com/p/mpmath/

सुविधाओं की सूची (अन्य के बीच)

अंकगणित:

  • मनमाना परिशुद्धता के साथ वास्तविक और जटिल संख्या
  • असीमित एक्सपोनेंट आकार / परिमाण

मुझे विशेष रूप से numpy के साथ कोई अनुभव नहीं है, लेकिन एक दशमलव अंक जोड़कर शून्य की एक निश्चित मात्रा में मदद मिल सकती है। उदाहरण के लिए, 1 के बजाय 1.0000 का उपयोग करें। सामान्य अजगर लिपियों में, जहां मुझे इस समस्या थी, इसने मदद की है, इसलिए जब तक कि आपकी समस्या किसी विषमता से नमी के कारण होती है और इसमें अजगर के साथ कुछ भी नहीं करना पड़ता है, तो इसे मदद करनी चाहिए।

सौभाग्य!


64-बिट सिस्टम पर, एक numpy.float128 dtype है (मेरा मानना ​​है कि 32-बिट सिस्टम पर फ्लोट float96 डीटीईपी भी है), जबकि numpy.linalg.eig 128-बिट फ़्लोट्स का समर्थन नहीं करता है, scipy.linalg.eig (प्रकार की) करता है

हालांकि, लंबे समय में, इनमें से कोई भी बात नहीं कर रहा है । एक eigenvalue समस्या के लिए किसी भी सामान्य solver को चलने वाला है, बल्कि सटीक, तो आप अतिरिक्त परिशुद्धता रखकर कुछ भी नहीं प्राप्त कर रहे हैं! np.linalg.eig किसी भी आकार के लिए काम करता है, लेकिन सटीक समाधान नहीं देता।

यदि आप हमेशा 2x2 मैट्रिक्स को हल कर रहे हैं, तो अपने स्वयं के सॉल्वर को लिखने के लिए तुच्छ है जो कि अधिक सटीक होना चाहिए। मैं इसके अंत में एक उदाहरण दिखाऊंगा ...

भले ही, निरर्थक सटीक स्मृति कंटेनर में आगे बढ़ाना:

import numpy as np
import scipy as sp
import scipy.linalg

a = np.array([[-800.21,-600.00],[-600.00,-1000.48]], dtype=np.float128)
ex = np.exp(a)
print ex

eigvals, eigvecs = sp.linalg.eig(ex)

# And to test...
check1 = ex.dot(eigvecs[:,0])
check2 = eigvals[0] * eigvecs[:,0]
print 'Checking accuracy..'
print check1, check2
print (check1 - check2).dot(check1 - check2), '<-- Should be zero'

हालांकि, आप देखेंगे कि जो भी आपको मिलता है वह सिर्फ np.linalg.eig(ex.astype(np.float64) करने के लिए समान है। वास्तव में, मुझे पूरा यकीन है कि यह क्या हो रहा है, जबकि numpy एक त्रुटि उठाता है यह चुपचाप करने से। हालांकि, मैं काफी गलत हूं, हालांकि ...

यदि आप ढीलापन का उपयोग नहीं करना चाहते हैं, तो एक कार्यवाही exponentiation के बाद चीजों को बचाना है, लेकिन eigenvalues ​​के लिए हल करने से पहले, उन्हें "सामान्य" फ़्लोट्स के रूप में डालें, eigenvalues ​​के लिए हल करें, और फिर चीजों को float128 के बाद के रूप में दोबारा दोबारा और पुनर्वित्त करें।

उदाहरण के लिए

import numpy as np

a = np.array([[-800.21,-600.00],[-600.00,-1000.48]], dtype=np.float128)
ex = np.exp(a)
factor = 1e300
ex_rescaled = (ex * factor).astype(np.float64)

eigvals, eigvecs = np.linalg.eig(ex_rescaled)
eigvals = eigvals.astype(np.float128) / factor

# And to test...
check1 = ex.dot(eigvecs[:,0])
check2 = eigvals[0] * eigvecs[:,0]
print 'Checking accuracy..'
print check1, check2
print (check1 - check2).dot(check1 - check2), '<-- Should be zero'

अंत में, यदि आप केवल 2x2 या 3x3 मैट्रिक्स को हल कर रहे हैं, तो आप अपना स्वयं का सॉल्वर लिख सकते हैं, जो मैट्रिक्स के उन आकृतियों के लिए एक सटीक मान वापस करेगा

import numpy as np

def quadratic(a,b,c):
    sqrt_part = np.lib.scimath.sqrt(b**2 - 4*a*c)
    root1 = (-b + sqrt_part) / (2 * a)
    root2 = (-b - sqrt_part) / (2 * a)
    return root1, root2

def eigvals(matrix_2x2):
    vals = np.zeros(2, dtype=matrix_2x2.dtype)
    a,b,c,d = matrix_2x2.flatten()
    vals[:] = quadratic(1.0, -(a+d), (a*d-b*c))
    return vals

def eigvecs(matrix_2x2, vals):
    a,b,c,d = matrix_2x2.flatten()
    vecs = np.zeros_like(matrix_2x2)
    if (b == 0.0) and (c == 0.0):
        vecs[0,0], vecs[1,1] = 1.0, 1.0
    elif c != 0.0:
        vecs[0,:] = vals - d
        vecs[1,:] = c
    elif b != 0:
        vecs[0,:] = b
        vecs[1,:] = vals - a
    return vecs

def eig_2x2(matrix_2x2):
    vals = eigvals(matrix_2x2)
    vecs = eigvecs(matrix_2x2, vals)
    return vals, vecs

a = np.array([[-800.21,-600.00],[-600.00,-1000.48]], dtype=np.float128)
ex = np.exp(a)
eigvals, eigvecs =  eig_2x2(ex) 

# And to test...
check1 = ex.dot(eigvecs[:,0])
check2 = eigvals[0] * eigvecs[:,0]
print 'Checking accuracy..'
print check1, check2
print (check1 - check2).dot(check1 - check2), '<-- Should be zero'

यह एक सही सटीक समाधान देता है, लेकिन यह केवल 2x2 मैट्रिक्स के लिए काम करेगा यह केवल एकमात्र समाधान है जो वास्तव में अतिरिक्त परिशुद्धता से लाभ, हालांकि!





arbitrary-precision