2015-11-10 5 views
6

scipy.sparse.spdiags या scipy.sparse.diags का उपयोग करते समय मैंने देखा है मैं एक बग के रूप में देखते दिनचर्यात्रुटि

scipy.sparse.spdiags([1.1,1.2,1.3],1,4,4).toarray() 

रिटर्न जैसे चाहते

array([[ 0. , 1.2, 0. , 0. ], 
     [ 0. , 0. , 1.3, 0. ], 
     [ 0. , 0. , 0. , 0. ], 
     [ 0. , 0. , 0. , 0. ]]) 

यह सकारात्मक विकर्णों के लिए है जो इसे पहले के डेटा को छोड़ देता है। कोई तर्क दे सकता है कि इसके लिए कुछ भव्य प्रोग्रामिंग कारण हैं और मुझे बस शून्य के साथ पैड करने की आवश्यकता है। ठीक है, जैसा कि हो सकता है, कोई scipy.sparse.diags का उपयोग कर सकता है जो सही परिणाम देता है। हालांकि इस दिनचर्या एक बग है कि चारों ओर

scipy.sparse.diags([1.1,1.2],0,(4,2)).toarray() 

काम नहीं किया जा सकता

array([[ 1.1, 0. ], 
     [ 0. , 1.2], 
     [ 0. , 0. ], 
     [ 0. , 0. ]]) 

अच्छा देता है, और

scipy.sparse.diags([1.1,1.2],-2,(4,2)).toarray() 

है

array([[ 0. , 0. ], 
     [ 0. , 0. ], 
     [ 1.1, 0. ], 
     [ 0. , 1.2]]) 

लेकिन

देता है
scipy.sparse.diags([1.1,1.2],-1,(4,2)).toarray() 

वैल्यूएरर कहने में त्रुटि देता है: विकर्ण लंबाई (ऑफसेट -1 पर सूचकांक 0: 2) मैट्रिक्स आकार (4, 2) से सहमत नहीं है। जाहिर है इस सवाल का जवाब

array([[ 0. , 0. ], 
     [ 1.1, 0. ], 
     [ 0. , 1.2], 
     [ 0. , 0. ]]) 

और अतिरिक्त यादृच्छिक व्यवहार के लिए हम

scipy.sparse.diags([1.1],-1,(4,2)).toarray() 

देने

array([[ 0. , 0. ], 
     [ 1.1, 0. ], 
     [ 0. , 1.1], 
     [ 0. , 0. ]]) 

किसी को भी पता है कि अगर वहाँ विकर्ण विरल मैट्रिक्स है कि वास्तव में काम करता है के निर्माण के लिए एक समारोह है है है?

+0

यह 'scipy.sparse.diags' में एक बग प्रतीत होता है। [स्रोत] को देखकर (https://github.com/scipy/scipy/blob/v0.16.1/scipy/sparse/construct.py#L63), हम देख सकते हैं कि विकर्ण लंबाई गणना 'm, n = आकार ... लंबाई = मिनट (एम + ऑफ़सेट, एन - ऑफसेट) ', और यह सही नहीं है। यह एक बग रिपोर्ट के लायक है। – user2357112

+0

अधिक जानकारी मेरे उत्तर में है। मुझे आश्चर्य है कि 'लंबाई = मिनट (एम + के, एन - के) 'सही' लंबाई 'है। यह सिर्फ संयोग हो सकता है कि 'ऑफ़सेट = -2' केस काम करता है। – hpaulj

+0

मुझे एक एसओ सवाल याद है जो मैटलैब समकक्ष के साथ 'spdiags' को विपरीत करता है। – hpaulj

उत्तर

2

कार्यकारी सारांश: spdiags ठीक से काम करता है, भले ही मैट्रिक्स इनपुट सबसे सहज नहीं है। diags में एक बग है जो आयताकार matrices में कुछ ऑफसेट को प्रभावित करता है। Scipy github पर एक बग फिक्स है।


उदाहरण spdiags के लिए है:

>>> data = array([[1,2,3,4],[1,2,3,4],[1,2,3,4]]) 
>>> diags = array([0,-1,2]) 
>>> spdiags(data, diags, 4, 4).todense() 
matrix([[1, 0, 3, 0], 
     [1, 2, 0, 4], 
     [0, 2, 3, 0], 
     [0, 0, 3, 4]]) 

ध्यान दें कि data 3 कॉलम हमेशा विरल 3 कॉलम में दिखाई देता है। अन्य कॉलम भी लाइन अप करते हैं। लेकिन वे छोड़े जाते हैं जहां वे किनारे से गिर जाते हैं।

इनपुट इस समारोह के लिए, एक मैट्रिक्स है, जबकि diags के लिए इनपुट एक प्रचंड सूची है। स्पैर मैट्रिक्स के विकर्णों में सभी के मूल्यों की अलग-अलग संख्या होती है। तो विनिर्देश को एक या दूसरे में इसे समायोजित करना है। spdiags कुछ इनपुट को अनदेखा करके, diags सूची इनपुट ले कर ऐसा करता है।

sparse.diags([1.1,1.2],-1,(4,2)) त्रुटि पेचीदा है।

spdiags बराबर करता है काम:

In [421]: sparse.spdiags([[1.1,1.2]],-1,4,2).A 
Out[421]: 
array([[ 0. , 0. ], 
     [ 1.1, 0. ], 
     [ 0. , 1.2], 
     [ 0. , 0. ]]) 

त्रुटि कोड के इस ब्लॉक में उठाया जाता है:

for j, diagonal in enumerate(diagonals): 
    offset = offsets[j] 
    k = max(0, offset) 
    length = min(m + offset, n - offset) 
    if length <= 0: 
     raise ValueError("Offset %d (index %d) out of bounds" % (offset, j)) 
    try: 
     data_arr[j, k:k+length] = diagonal 
    except ValueError: 
     if len(diagonal) != length and len(diagonal) != 1: 
      raise ValueError(
       "Diagonal length (index %d: %d at offset %d) does not " 
       "agree with matrix size (%d, %d)." % (
       j, len(diagonal), offset, m, n)) 
     raise 

diags में वास्तविक मैट्रिक्स निर्माता है:

dia_matrix((data_arr, offsets), shape=(m, n)) 

यह वही निर्माता है जो spdiags उपयोग करता है, bu बिना किसी हेरफेर के टी।

In [434]: sparse.dia_matrix(([[1.1,1.2]],-1),shape=(4,2)).A 
Out[434]: 
array([[ 0. , 0. ], 
     [ 1.1, 0. ], 
     [ 0. , 1.2], 
     [ 0. , 0. ]]) 

dia प्रारूप में, आदानों वास्तव में जमा हो जाती है spdiags (अतिरिक्त मूल्यों के साथ कि मैट्रिक्स के साथ पूर्ण) द्वारा दिए गए के रूप में:

In [436]: M.data 
Out[436]: array([[ 1.1, 1.2]]) 
In [437]: M.offsets 
Out[437]: array([-1], dtype=int32) 

@user2357112 के रूप में अंक बाहर, length = min(m + offset, n - offset, गलत है उत्पादन परीक्षण मामले में । इसे length = min(m + k, n - k) में बदलना इस (4,2) मैट्रिक्स कार्य के लिए सभी मामलों को बनाता है। यह सुधार, diags([1.1,1.2], 1, (2, 4)) काम करता है के साथ

https://github.com/pv/scipy-work/commit/529cbde47121c8ed87f74fa6445c05d71353eb6c

length = min(m + offset, n - offset, min(m,n)) 

:, diags([1.1,1.2], 1, (2, 4))

सुधार, अक्टूबर 5 के रूप में के लिए इस मुद्दे को है: लेकिन यह पक्षांतरित साथ विफल रहता है।

+0

हाँ, लेकिन 'scipy.sparse.diags ([1.1,1.2], - 1, (4,2))। Toarray() 'उदाहरण देखें। उसे काम करना चाहिए, लेकिन यह 'diags' कार्यान्वयन में गलत विकर्ण लंबाई गणना मार रहा है। – user2357112

+0

कौन बग रिपोर्ट दर्ज करना चाहता है, या कम से कम मौजूदा लोगों की खोज करना चाहते हैं? :) मैंने 'numpy' में योगदान दिया है, लेकिन अभी तक' scipy' नहीं है। – hpaulj

+0

मैं कभी भी गिटहब खाता बनाने के लिए नहीं मिला, इसलिए मैं रिपोर्ट दर्ज नहीं कर सकता। आप इसे भी कर सकते हैं। मुझे नहीं लगता कि 'ऑफसेट 'को' k' में बदलना बग को ठीक करता है, हालांकि। असफल परीक्षण मामले के हस्तांतरण के साथ समस्या अभी भी होनी चाहिए: 'scipy.sparse.diags ([1.1,1.2], 1, (2, 4))। Toarray()' – user2357112

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