2017-05-21 5 views
14

मैं सेल सेल में प्रत्येक सेल में फ़ंक्शन लागू करने के लिए cellfun का उपयोग कर रहा हूं।{} ऑपरेटर के साथ फ़ंक्शन को 'यूनिफॉर्मऑटपुट' का वैध प्रतिस्थापन, सेलफन में गलत लपेट रहा है?

मुझे पता है कि जब भी फ़ंक्शन गैर-स्केलर मान देता है तो मुझे 'UniformOutput' से false सेट करना होगा, ताकि फ़ंक्शन के आउटपुट को सेल सरणी में encapsulated वापस कर दिया जाए।

एक उदाहरण के रूप में निम्नलिखित सेल सरणी लें:

C1 = {[1 2 3], [4 5 6]}; 

C1 दो कोशिकाएं होती हैं और प्रत्येक कोशिका तीन तत्वों का एक वेक्टर शामिल हैं:

C1 = 

    1×2 cell array 

    [1×3 double] [1×3 double] 

अगर मैं सामग्री के 1 जोड़ना चाहते हैं प्रत्येक सेल में, मैं @(x) x + 1 फ़ंक्शन को परिभाषित कर सकता हूं और cellfun का उपयोग करके इसे लागू कर सकता हूं:

C2 = cellfun(@(x) x + 1, C1, 'UniformOutput', false); 

यह बहुत अच्छा काम करता है, लेकिन ध्यान दें कि मुझे यह सुनिश्चित करने की ज़रूरत है कि 'UniformOutput'false पर सेट है जैसा कि मैंने पहले बताया था, अन्यथा एक त्रुटि फेंक दी जाएगी।

हालांकि, this thread पढ़ने के बाद, मुझे एहसास हुआ कि अगर मैं cell array construction operator {} इस तरह के साथ समारोह लपेट @(x) {x + 1} तो मैं false को 'UniformOutput' निर्धारित करने की आवश्यकता नहीं है।

तो निम्न आदेश किसी भी त्रुटि फेंक बिना C2 में के रूप में एक ही परिणाम उत्पन्न करेगा:

C3 = cellfun(@(x) {x + 1}, C1); 

कोड लेआउट मैं इस दृष्टिकोण पसंद करते हैं, क्योंकि यह अधिक कॉम्पैक्ट और पूर्व की तुलना में कम वर्बोज़ है के संदर्भ में, लेकिन मुझे यकीन नहीं है कि यह हमेशा सुरक्षित है या नहीं।


इस प्रकार मेरे सवाल है:

मैं हमेशा {} साथ समारोह लपेट कर सकते हैं false को 'UniformOutput' स्थापित करने से बचने के लिए? या क्या ऐसे कोई परिदृश्य हैं जहां ऐसे प्रतिस्थापन काम नहीं करेंगे?


मेरे शोध:

help cellfun 

'UniformOutput' - किसी तार्किक मान का संकेत है या नहीं, FUN की उत्पादन (रों) एक सेल सरणी में कैप्सूलीकरण बिना वापस किया जा सकता। यदि true (डिफ़ॉल्ट), FUN को स्केलर मान वापस करना होगा जो को किसी सरणी में सम्मिलित किया जा सकता है। यदि true, आउटपुट निम्न प्रकारों का होना चाहिए: संख्यात्मक, तार्किक, चार, संरचना, सेल। यदि false, cellfun एक सेल सरणी (या एकाधिक सेल सरणी), देता है जहां (I, J, ...) th सेल में मान FUN (C {I, J, ...}, ...) है । जब 'UniformOutput'false है, तो आउटपुट किसी भी प्रकार का हो सकता है।

निम्नलिखित टुकड़ा एक संबंधित सवाल का an answer का हिस्सा है:

[...] cellfun भिन्नता आपरेशन जो एक सेल के अलग-अलग तत्वों के बारे में विस्तृत संचालन करने के लिए आवश्यक है का ख्याल रखता है जब पाशन (जो है, {}) [...]

उत्तर

15

दो स्थितियों मैं कहाँ में cell encapsulation का उपयोग कर के बारे में सोच सकते हैं

  • कैप्चरिंग कई आउटपुट: कभी कभी तुम समारोह आप कर रहे हैं से कई आउटपुट पर कब्जा करने के लिए कर सकते हैं अतिरिक्त तर्कों की जगह ...'UniformOutput', false) एक समस्या का कारण होता है, पहले एक दूसरे की तुलना में काफी अधिक होने की संभावना परिदृश्य किया जा रहा है आवेदन करना, जैसे कि unique को अपने सेल सरणी के प्रत्येक तत्व पर कॉल करना और अतिरिक्त अनुक्रमणिका तर्क प्राप्त करना। ...'UniformOutput', false) इस्तेमाल करते हुए हम आसानी से कर सकते हैं:

    >> C1 = {[1 2 3], [4 5 6]}; 
    >> [C2, index] = cellfun(@(x) unique(x), C1, 'UniformOutput', false) 
    C2 = 
        1×2 cell array 
        [1×3 double] [1×3 double] 
    index = 
        1×2 cell array 
        [3×1 double] [3×1 double] 
    

    बहरहाल, यह विफल रहता है जब सेल कैप्सूलीकरण का उपयोग कर: कोई उत्पादन के साथ

    >> [C2, index] = cellfun(@(x) {unique(x)}, C1) 
    Output argument "varargout{2}" (and maybe others) not assigned during call to 
    "@(x){unique(x)}". 
    
  • कार्य: मुझे पता है तुम क्या सोच रहे हैं: "लेकिन अगर वे कोई आउटपुट नहीं देते हैं, तो मुझे गैर-स्केलर मूल्यों को इकट्ठा करने की चिंता करने की ज़रूरत नहीं है! " सच है, लेकिन मैं एक स्वीकार्य असामान्य परिदृश्य की कल्पना कर रहा हूं जहां मूल्यांकन का कार्य एक अतिरिक्त पैरामीटर हो सकता है, जैसे फ़ंक्शन हैंडल एक तर्क के रूप में पारित किया गया है, इसलिए आप को प्राथमिकता नहीं जानते हैं कि आप कितने आउटपुट होंगे साथ बर्ताव करना। भले ही, दो दृष्टिकोण तरह के एक मामले के लिए अलग:

    >> C1 = {[1 2 3], [4 5 6]}; 
    >> cellfun(@(x) disp(x), C1, 'UniformOutput', false); 
        1  2  3 
        4  5  6 
    
    >> cellfun(@(x) {disp(x)}, C1); 
    Error using disp 
    Too many output arguments. 
    Error in @(x){disp(x)} 
    

    शायद कुछ तुम कभी के बारे में चिंता करना होगा नहीं है, लेकिन मैंने सोचा कि मैं यह पूर्णता के लिए के लिए शामिल था।

+0

वाह .. मुझे नहीं पता था कि 'सेलफन' के साथ कई आउटपुट कैप्चर करना भी संभव था। यह एक प्रबुद्ध जवाब है! धन्यवाद :) – codeaviator

2

आप से सवाल ...

मैं हमेशा के साथ समारोह में लपेट कर सकते हैं {} गलत पर 'UniformOutput' की स्थापना से बचने के लिए? या क्या ऐसे कोई परिदृश्य हैं जहां ऐसे प्रतिस्थापन काम नहीं करेंगे?

संक्षिप्त उत्तर "नहीं" है। और मेरा मानना ​​है कि आपका अज्ञात फ़ंक्शन असफल होने का मुख्य कारण यह है कि इसमें टाइपिंग की कमी है और प्रोग्रामर को फ़ंक्शन रिटर्निंग प्रकार के बारे में भी कम जानकारी नहीं है।

असल में, आईएमओ आपको सेल इंडेक्सिंग ऑपरेटरका उपयोग करके अपने वापसी मूल्य को लपेटने के लिए या अपने अज्ञात फ़ंक्शन में नहीं पर संघर्ष करना चाहिए। एक बेहतर अभ्यास cellfun पर कॉल करने के बाद वापसी मूल्य प्रकार निर्धारित करना होगा या cellfun पर कॉल करने से पहले इनपुट मान प्रकार की जांच करना होगा। निश्चित रूप से, आप अपने function handle में टाइपिंग प्रक्रिया या try...catch को अपने रिटर्न प्रकार के पूर्ण नियंत्रण को सुनिश्चित करने के लिए भी कार्यान्वित कर सकते हैं। और ईमानदार होने के लिए, आप जो भेजते हैं उसे जानना और आप जो प्राप्त करने जा रहे हैं वह मैटलैब में बेहद महत्वपूर्ण है।

संक्षेप में, आपको अपने अज्ञात फ़ंक्शन को समाहित करने के लिए {} का उपयोग नहीं करना चाहिए जबतक कि आप जानबूझकर रिटर्न प्रकार के रूप में सेल सरणी नहीं बनाते हैं, और आप जानते हैं कि आपके द्वारा बुलाए गए फ़ंक्शन से वापसी मूल्य का उपयोग किया जा सकता है एक सेल सरणी बनाने के लिए।

एफवाईआई, यदि आपके पास 2016 बी या बाद में है, जबकि function in script is possible, तो आप cellfun के लिए एक नई फ़ाइल बनाने के बिना अपनी स्क्रिप्ट के भीतर फ़ंक्शन हैंडल बना सकते हैं।

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